我们为什么要指定<>与缺省参数模板类?(Why do we have to specif

2019-09-23 15:14发布

我发现在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参数的一类,我觉得对于最终用户这个不方便:他应该能够使用默认的实现作为一个没有模板类...

Answer 1:

为什么这种行为的原因是什么?

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

当你写一个函数调用时,编译器填充的所有可以使用该名称查找功能的重载集合,然后计算出哪些传入的参数(或多个)相匹配。 现在,这个干净与函数模板的工作,它允许模板参数类型从参数推断。 因为类型参数推断是允许在一般情况下,它是否适合你的情况下,即使该参数,而不是默认。

类型,然而,没有超载。 虽然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 (按雷米的评论)是最好的选择。



Answer 2:

myClass是类模板,而不是一类。 只有myClass<true> ,或myClass<>是一类。

同样, myFunction是一个函数模板,不是一个函数。 然而,当你调用一个模板函数,模板参数可以推断出你的,而你并不需要显式地指定模板参数,如果他们可以推断出。 因此,该函数调用表达式myFunction(); 是有效的,并且第一个参数推导出false 。 这只是扣除发生多亏了默认参数,而不是对函数的参数匹配。



文章来源: Why do we have to specify <> for a template class with default parameters?