我发现 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 !
为什么会出现这种行为的原因呢?
有什么技巧可以避免这种情况吗?
对于具有作为模板传递的可选参数的类,我发现这对最终用户来说并不方便:他应该能够使用默认实现作为非模板化类...
为什么会出现这种行为的原因呢?
这是因为函数可以重载,而类型则不能。
当您编写函数调用时,编译器会填充它可以找到的具有该名称的所有函数的重载集,然后找出哪些函数与传递的参数匹配。现在,为了使其能够与函数模板完美配合,它允许从参数推导模板参数类型。由于类型参数推断通常是允许的,因此即使参数是默认的,它也适用于您的情况。
然而,类型并没有超载。尽管myFunction<true>()
and myFunction<false>()
都与它们参与相同过载集的程度有关,myClass<true>
and myClass<false>
是分开的并且无关类型。由于没有相当于类型名称重载的功能,因此没有动力添加特殊情况来隐式命名完全专用的模板类。这些参数永远无法推断出来,因此仅在它们全部默认的情况下才相当于特殊语法。
有什么技巧可以避免这种情况吗?
一般来说,如果你想获得模板类的模板参数推导,你可以提供一个模板函数包装器(这最适合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
(根据雷米的评论)是最好的选择。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)