为什么可选参数不适用于模板?

时间:2012-09-23 18:15:54

标签: c++ templates optional-parameters

为什么带有模板函数的可选参数在C ++中不起作用?

(澄清:我希望了解为什么 C ++的设计使得这是不可能的。)

#include <iostream>
template<class T1, class T2> T1 inc(T1 v, T2 u = 1) { return v + u; }
int main() { std::cout << inc(5); }
  

prog.cpp:在函数‘int main()’中:错误:没有匹配函数来调用‘inc(int)’

4 个答案:

答案 0 :(得分:3)

你错了路。默认参数不参与参数推导:

参数推断首先发生 ,作为选择所需重载的一部分,然后必要时填充该重载的默认参数。

答案 1 :(得分:2)

Kerrek SB所说的是正确的,编译器只是没有足够的推断T2(从标准允许的内容)。

在这种特殊情况下,您可以通过仅使用一个模板参数来修复它,即

template< class T > T inc( const T v, const T u = 1 ) { return v + u; }

答案 2 :(得分:1)

默认参数不参与演绎过程(仅限于重载决策,规则很难记住 - 始终保持简单)。

要实现您的目标,您可以提供额外的重载:

template <class T1, class T2> T1 inc(T1 v, T2 u) { return v + u; }
template <class T> T inc(T v) { return v + T(1); }

答案 3 :(得分:0)

C ++中的模板函数是在编译时生成的,只有在需要时才会生成。所以你可以得到一个生成的函数,如:

inc( int, int );

这是T1 = int和T2 = int版本。如果为每个模板参数传入参数,编译器可以隐式确定类型,所以:

int a = 1;
int b = 2;
inc( a, b );

编译器可以在编译时生成类似上面的函数,因为它可以推断出T1 = int和T2 = int。但是,如果你做了你正在做的事情:

inc( 5 );

编译器可以确定T1 = int,但它无法确定T2是什么。因此,不会生成任何函数,并且您会收到有关函数不存在的错误。如果您使用一个模板参数,则可以修复此问题:

template<class T> T inc(T v, T u = 1) { return v + u; }

或者如果你提供过载:

template<class T> T inc(T v) { return v + 1; }

还有第三种方式:

inc<int, int>( 5 );

但我想这不是你想要的......