我发现在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 !
为什么这种行为的原因是什么? 有没有什么办法来避免呢? 对于作为模板通过optionnal参数的一类,我觉得对于最终用户这个不方便:他应该能够使用默认的实现作为一个没有模板类...
为什么这种行为的原因是什么?
这是因为函数可以被重载,并且类型不能。
当你写一个函数调用时,编译器填充的所有可以使用该名称查找功能的重载集合,然后计算出哪些传入的参数(或多个)相匹配。 现在,这个干净与函数模板的工作,它允许模板参数类型从参数推断。 因为类型参数推断是允许在一般情况下,它是否适合你的情况下,即使该参数,而不是默认。
类型,然而,没有超载。 虽然myFunction<true>()
和myFunction<false>()
都与他们会参与相同的过载设定的范围内, myClass<true>
和myClass<false>
是分开的, 不相关的类型。 由于没有相当于超载对类型名称,也没有动机来添加一种特殊情况隐式命名一个完全专业的模板类。 该参数永远不能被推断,所以就相当于特殊的语法只为他们所有拖欠的情况。
有没有什么办法来避免呢?
一般来说,如果你想获得模板类模板参数推导,你可以提供一个模板函数包装(这个工作最好与C ++ 11汽车)
template <bool Option=false> class MyClass {};
template <bool Option=false> MyClass<Option> make_my_class() {
return MyClass<Option>();
}
// ...
auto z = make_my_class();
否则,我想使用typedef
(按雷米的评论)是最好的选择。
myClass
是类模板,而不是一类。 只有myClass<true>
,或myClass<>
是一类。
同样, myFunction
是一个函数模板,不是一个函数。 然而,当你调用一个模板函数,模板参数可以推断出你的,而你并不需要显式地指定模板参数,如果他们可以推断出。 因此,该函数调用表达式myFunction();
是有效的,并且第一个参数推导出false
。 这只是扣除发生多亏了默认参数,而不是对函数的参数匹配。