![](/img/trans.png)
[英]Why does this template argument deduction fail when a default value is given?
[英]Why does template parameter deduction fail when calling the constructor like this?
以下内容无法编译:
struct S {
template <class T> S(T) {}
};
void f(int) {}
int main() {
S(f);
}
g ++-4.9说
template.cpp: In function ‘int main()’:
template.cpp:6:8: error: no matching function for call to ‘S::S()’
S(f);
^
template.cpp:6:8: note: candidates are:
template.cpp:2:24: note: template<class T> S::S(T)
template <class T> S(T) {}
^
template.cpp:2:24: note: template argument deduction/substitution failed:
template.cpp:6:8: note: candidate expects 1 argument, 0 provided
S(f);
^
template.cpp:1:8: note: constexpr S::S(const S&)
struct S {
^
template.cpp:1:8: note: candidate expects 1 argument, 0 provided
template.cpp:1:8: note: constexpr S::S(S&&)
template.cpp:1:8: note: candidate expects 1 argument, 0 provided
铛给出了类似的错误。
另一方面,将编译以下内容:
struct S {
template <class T> S(T) {}
};
void f(int) {}
int main() {
S s = S(f); // this line was changed
}
那么这是怎么回事?
问题
您编写的代码并不代表您的实际意思,实际上是在声明名称为f
的类型S
的变量; 它不是使用f
作为参数构造S
类型的未命名实体。
注意:当您将行更改为S s = S(f)
您将声明一个名为s
的类型为S
的变量,并使用临时S(f)
初始化(即S的副本构造函数将用于初始化s
)。
解决方案
将类型包装在括号中,或使用统一初始化 (在C ++ 11中引入)。
(S) (f); // creates a temporary of type S initialized with `f`
S { f }; // c++11
原因
标准( n3797 )表示,声明变量时T(x)
等于T x
,如以下部分所示:
8.3p6 声明符的含义
[dcl.meaning]
意义[dcl.meaning]
在声明
TD
,D
具有以下形式( D1 )
所包含的说明符-ID的类型是一样的,在声明的说明符包含-ID的
T D1
括号不会更改嵌入的声明符id的类型,但是可以更改复杂声明符的绑定。
用你对struct S
的定义
int main() {
S(f); // 1 <-----+
S s(f); // 2 <-------+ // +---- SAME
S s1 ; // +---- SAME // 3 <-----+
S s2 = S(f) ; // 4 <-------+
}
S
的变量f
和s1
需要初始化的构造函数 S
的变量s
和s2
(请注意,这里的f
不是您的函数名)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.