【问题标题】:Why do we have to specify <> for a template class with default parameters?为什么我们必须为具有默认参数的模板类指定 <>?
【发布时间】:2012-09-27 04:22:18
【问题描述】:

我在 C++ 中发现了一些烦人的东西,我不知道是否有一个技巧可以避免这种情况而不会产生任何开销。问题如下:

对于模板函数,我们可以有:

// Function declaration/definition
template<bool Option = false> void myFunction() 
{
    std::cout<<"Option = "<<Option<<std::endl;
}

// Then I can use :
myFunction<false>();
myFunction<true>();
myFunction(); // <- NO PROBLEM HERE

现在是模板类:

// Class definition/declaration
template<bool Option = false> class MyClass
{
};

// Then I can use :
myClass<false> x;
myClass<true> y;
myClass z; // <- PROBLEM HERE : only "MyClass<> z;" will compile !

为什么会出现这种行为? 有什么技巧可以避免这种情况吗? 对于具有作为模板传递的可选参数的类,我发现这对最终用户来说并不方便:他应该能够将默认实现用作无模板类...

【问题讨论】:

  • "有什么技巧可以避免这种情况吗?" 不,除非您考虑创建一个新类型(使用不同的名称),该类型从它公开继承并转发所有构造函数。
  • 或者只使用 typedef 而不是继承:typedef myClass&lt;false&gt; myClassDef;
  • @Remy :哦,是的,或者那个。 :-P 我想我的大脑已经完成了这一天。

标签: c++ class templates c++11 default-value


【解决方案1】:

为什么会出现这种行为?

这是因为函数可以重载,而类型不能。

当您编写函数调用时,编译器会使用该名称填充它可以找到的所有函数的重载集,然后确定哪些函数与传递的参数匹配。现在,为了让它与函数模板一起干净地工作,它允许从参数中推断出模板参数类型。因为通常允许类型参数推断,所以即使参数是默认值,它也适用于您的情况。

然而,类型并没有被重载。虽然myFunction&lt;true&gt;()myFunction&lt;false&gt;() 都与它们参与同一重载集的程度相关,但myClass&lt;true&gt;myClass&lt;false&gt; 是独立且不相关的类型。由于没有等效于类型名称的重载,因此没有动机添加一个特殊情况来隐式命名一个完全专业化的模板类。参数永远不能被推断出来,所以只有在它们都被默认的情况下才会有特殊的语法。

有什么技巧可以避免吗?

一般来说,如果你想得到模板类的模板参数推导,你可以提供一个模板函数包装器(这最适合C++11 auto)

template <bool Option=false> class MyClass {};
template <bool Option=false> MyClass<Option> make_my_class() {
    return MyClass<Option>();
}
// ...
auto z = make_my_class();

否则,我认为使用typedef(根据 Remy 的评论)是最好的选择。

【讨论】:

    【解决方案2】:

    myClass 是类模板,而不是类。只有myClass&lt;true&gt;myClass&lt;&gt; 是一个类。

    同样,myFunction 是函数模板,而不是函数。但是,当您调用模板化函数时,可能会为您推导出模板参数,如果可以推导出模板参数,您不需要显式指定模板参数.因此函数调用表达式myFunction();是有效的,第一个参数推导出为false。只是由于默认参数而不是与函数参数匹配而进行推导。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-01
      • 1970-01-01
      • 2012-06-29
      • 2014-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多