gpt4 book ai didi

c++ - C++11 中的默认构造函数、POD 的初始化和隐式类型转换

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:02:46 26 4
gpt4 key购买 nike

我刚看了 Chandler 在 Going Native 2012 上关于 Clang 的演讲。他展示了以下代码:

#include <iostream>

struct S{ int n; };
struct X{ X(int) {}; };

void f( void* )
{
std::cerr << "Pointer!\n";
}

void f( X )
{
std::cerr << "X!\n";
}

int main()
{
f(S().n);
}

Chandler 指出,这为 c++11 调用了 f(void*),为 c++03 调用了 f(X)。他还指出,原因是 S().n 默认初始化为 0,使其成为 nullptr 常量。

首先,我假设成员变量 n 的零初始化依赖于编译器实现并且不受标准保证(或者这是否随 c++11 发生了变化)? Chandler 暗示这是由于支持常量表达式,但我仍然不能完全理解他的推理。

其次,为什么 f(X) 会被 C++03 而不是 c++11 调用?我假设 f(void*) 会在隐式转换为 X 时不管 S().n 的值如何

有关钱德勒的解释,请参阅以下链接,45 分钟内:

Clang: Defending C++ from Murphy's Million Monkeys

最佳答案

Firstly am I right in assuming that the zero initialization of member variable n is compiler implementation dependent and NOT guaranteed by the standard (or did this change with c++11)?

不,S() 在 C++03 和 C++11 中都表示值初始化。虽然我相信 C++11 中的措辞比 C++03 中的措辞更清晰。在这种情况下,值初始化转发到零初始化。将此与不为零的默认初始化进行对比:

S s1;  // default initialization
std::cout << s1.n << '\n'; // prints garbage, crank up optimizer to show
S s2 = S(); // value initialization
std::cout << s2.n << '\n'; // prints 0

Secondly why would f(X) be called with C++03 and not c++11? I would of assumed that f(void*) would kick in regardless of the value of S().n over an implicit conversion to X

在 C++03 中,int 永远不会成为空指针常量。一旦 0 被输入为 int,比如将其分配给 int,那么它永远是 int , 而不是空指针常量。

在 C++11 中,S().n 隐式地是一个 constexpr 表达式,其值为 0,并且一个 constexpr 值为 0 的表达式可以是空指针常量。

最后,据我所知,这并不是委员会有意做出的改变。如果您正在编写依赖于这种差异的代码,那么如果/当委员会自行纠正时,您将来很可能会被咬。我会避开这个区域。用它来赢得酒吧赌注——而不是在生产代码中。

关于c++ - C++11 中的默认构造函数、POD 的初始化和隐式类型转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9515327/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com