【问题标题】:How to overload template class by type- and non-type template parameters?如何通过类型和非类型模板参数重载模板类?
【发布时间】:2018-12-13 22:45:09
【问题描述】:

是否可以实现支持以下实例化的模板类Type

Type<int> typeArg_;
Type<nullptr> nonTypeArg_;

我希望有一个解决方案(尤其是没有宏)。也许std::enable_if-magic 或其他东西会有所帮助......

【问题讨论】:

    标签: c++ class templates overloading metaprogramming


    【解决方案1】:

    不,你不能那样做。

    模板参数的性质是固定的。它是类型或非类型(值)。它不能是一个用例的类型而另一个用例的非类型。

    如果你能详细说明那是什么,可能会有一些方法可以实现你的目标。

    【讨论】:

      【解决方案2】:

      就我现在而言,在 C++ 中是不可能的。

      我想到的最好的方法是将值包装在类型中;像

      template <typename T, T Value>
      struct ValueWrapper
       { };
      

      并将Type 专门用于ValueWrapper

      某事

      template <typename T>
      struct Type
       { /* something with T */ };
      
      template <typename T, T Value>
      struct Type<ValueWrapper<T, Value>>
       { /* something with value */ };
      

      使用变成

      Type<int>  typeArg;
      Type<ValueWrapper<std::nullptr_t, nullptr>> nonTypeArg;
      
      or also
      
      Type<ValueWrapper<decltype(nullptr), nullptr>> nonTypeArg;
      

      正如 Jarod42 所指出的(感谢),标准(从 C++11 开始)提供了一个标准结构,使 ValueWrapper 函数:std::integral_constant

      您可以使用它来代替ValueWrapper,但它不起作用,对于std::integral_constant,以下C++17 示例。

      因为如果你能用C++17,一切都变得简单了:你可以用auto作为值类型,所以ValueWrapper就变成了

      template <auto Value>
      struct ValueWrapper
       { };
      

      所以Type非类型特化变成了

      template <auto Value>
      struct Type<ValueWrapper<Value>>
       { /* something with value */ };
      

      及用途

      Type<int>  typeArg;
      Type<ValueWrapper<nullptr>> nonTypeArg;
      

      【讨论】:

      • 为什么不std::integral_constant
      • 因为 (1) 我不记得它(我的错)和 (2) 我正在考虑修改 auto 版本的 C++17 案例。但我会添加一个关于它的注释。谢谢。
      猜你喜欢
      • 2021-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-08
      • 2011-08-06
      相关资源
      最近更新 更多