C 11:分配给匿名实例的原始类型的默认构造函数

前端之家收集整理的这篇文章主要介绍了C 11:分配给匿名实例的原始类型的默认构造函数前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
请考虑以下代码
#include <iostream>

template<class T>
void f(T& t)
{
    t = T();
}

int main()
{
    int x = 42;
    f(x);
    std::cout << x;
}

C 11标准是否定义输出是什么?我的编译器输出0,但是我的印象是原始类型的默认构造函数是空操作或未定义的行为.

解决方法

您的代码中没有“默认构造函数”.只有类类可以有构造函数.标量类型没有构造函数,默认值或其他值.

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()表达式仍然可以完全忽略它,而是通过自己的规则工作.

猜你在找的C&C++相关文章