请考虑以下代码:
#include <iostream> template<class T> void f(T& t) { t = T(); } int main() { int x = 42; f(x); std::cout << x; }
解决方法
您的代码中没有“默认构造函数”.只有类类可以有构造函数.标量类型没有构造函数,默认值或其他值.
T()语法创建一个由所谓的值初始化初始化的临时对象.价值初始化仅适用于类类型的构造函数调用,仅适用于具有用户定义构造函数的构造函数(在C 11中有一些细微差别).对于其他类型,值初始化根本不涉及任何构造函数.它根据自己的具体且相当复杂的初始化规则进行,它直接定义数据的初始值,而不涉及任何构造函数(见语言规范中的8.5).
对于标量类型,值初始化执行零初始化.这就是为什么你的代码保证输出为零.抽象初始化过程的具体细节在C语言标准版本之间发生了变化,但是从时间开始,C语言保证T == int的T()表达式被计算为零.即即使在C 98中,代码将输出为零.
所有这些T(…)表达式都不一定意味着构造函数调用是一个常见的误解.实际上,T(…)表达式是一个功能转换表达式(不论参数的数量)(参见语言规范中的5.2.3),可能在一些狭窄的特定情况下解决构造函数的调用,并且没有任何内容在其他情况下与任何构造函数有关.
例如,这段代码
struct S { int x,y; }; S s = S();
保证用零初始化s(即,s.x和s.y都将为零),尽管类S具有不执行任何操作的默认构造函数.我特意提出了这个例子来说明即使在默认构造函数存在的情况下,T()表达式仍然可以完全忽略它,而是通过自己的规则工作.