【问题标题】:Passing Class as a Non-type argument in templates in c++在 C++ 中的模板中将类作为非类型参数传递
【发布时间】:2013-05-20 11:48:57
【问题描述】:

在我研究的模板中,我们只能有整数参数,即 int、指向其他数据类型的指针以及模板模板参数。

但是在这里我可以只传递一个简单的类也作为模板参数。这是有效的还是我的理解是错误的。这是一段代码。

template <typename T> 
class A {
  public:
         T t;             
};
class B {
  public:
         float f;      
};
template <template<typename> class X, class H> 
class C {
   public:
          H obj;
          X<int> x;                                
};
int main()
{
    C < A, B > my;
    my.obj.f = 2.3f;
    my.x.t = 5;
    cout << "template class object: " << my.obj.f << endl;
    cout << "class object         : " << my.x.t << endl;
}

【问题讨论】:

    标签: c++ templates template-templates class-template


    【解决方案1】:

    模板参数分为三种:

    • 类型参数,type 必须作为参数提供(例如intstd::string 等)。在您的示例中,H 是一个类型参数;
    • 非类型参数,必须作为参数提供(例如42)。您的示例不包含任何这些内容;
    • 模板参数,必须为其提供一个类模板(接受正确数量和类型的参数)。在您的示例中,A 是一个模板参数。

    在我研究的模板中,我们只能有整数参数,即 int、指向其他数据类型的指针以及模板模板参数。

    你在上面这句话的第一部分所指的适用于第二类参数,即非类型参数,而这句话的最后部分涵盖了模板模板参数。

    确实,非类型参数需要特定类型的值,例如int, X* 在实例化模板时作为参数传递,并且有严格的限制:

    • 可以指定的类型;
    • 可以指定的值的性质。

    例如,这是禁止的:

    template<double D>
    struct X { /* ... */ };
    

    虽然这是允许的:

    template<int* P>
    struct X { /* ... */ };
    

    但是对于可以作为 P 的参数提供的内容受到限制:

    int main()
    {
        int x = 42;
        X<&x> obj; // ERROR!
    }
    

    您上面的句子没有涵盖的部分是第一类(类型参数),这实际上是最常见的一类。除其他外,类型参数用于实例化对象的通用集合,例如:

    std::vector<my_class> v;
    

    【讨论】:

    • double(or float) 即使在 c++11 中也不允许作为非类型模板参数?
    • 除了历史,还有什么原因吗?
    • @Koushik:虽然我不知道这不可能的确切技术原因是什么,但我可以想象模板专业化是其中之一:专门针对某个论点(例如 template&lt;&gt; class my_template&lt;3.14&gt; { ... };)需要判断浮点数之间是否相等,而判断浮点数之间是否相等比较麻烦。
    • 如果我写 typename H 它可以工作,但如果我写 typename X 那么它会给我错误。为什么?因为我们可以同时使用 typename 和 class。
    • @Gaurav:对于模板模板参数,唯一允许的关键字是class。对于类型参数,classtypename 可以互换使用
    猜你喜欢
    • 2019-04-24
    • 2016-10-20
    • 1970-01-01
    • 2015-07-29
    • 2021-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多