默认构造函数,POD的初始化和C ++ 11中的隐式类型转换 [英] Default constructors, initialization of POD and implicit type conversions in C++11

查看:201
本文介绍了默认构造函数,POD的初始化和C ++ 11中的隐式类型转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚看过Chandler在Going Native 2012上的Clang演讲。他提供了以下代码:

I have just watched Chandler's presentation on Clang at Going Native 2012. He presents the following code:

#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声明这会调用 f 用于c ++ 11和 f(X)用于c ++ 03。
他还说,原因是S().n默认初始化为0,使它成为一个 nullptr 常量。

Chandler states that this calls f(void*) for c++11 and f(X) for c++03. He also states that the reason is that S().n is default initialised to 0, making it a nullptr constant.

首先我假定成员变量n的零初始化是依赖于编译器实现的,并且不被标准保证(或者使用c ++ 11进行这种更改)? Chandler提示这是由于支持常量表达式,但我仍然不能完全按照他的推理。

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)? Chandler hints this is due to support for constant expressions but I still cannot fully follow his reasoning.

其次为什么 f(X)用C ++ 03而不是c ++ 11调用?我会假设 f(void *)将会启动,而不管 S()的值。n over隐式转换为 X

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

对于Chandler的解释,看下面的链接,45分钟:

For Chandler's explanation see the following link, 45 minutes in:

Clang:从Murphy的百万猴子中保护C ++

推荐答案


我是正确的假设成员
变量n的零初始化是编译器实现依赖和不保证由
标准(或与c + + 11这样的更改)?

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更清楚。在这种情况下,值初始化转向零初始化。对比此默认初始化不为零:

No, S() means value initialize in both C++03 and C++11. Though I believe the wording for this is much clearer in C++11 than C++03. In this case, value-initialization forwards to zero-initialization. Contrast this with default-initialization which does not zero:

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




其次,为什么要调用f C ++ 03而不是c ++ 11?我想
假设f(void *)将在不考虑S()的值的情况下进入。n
对X的隐式转换

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 ,而不是空指针常量。

In C++03 an int can never become a null pointer constant. Once 0 is typed as an int, say by assigning it to an int, then it is forever an int, and not a null pointer constant.

+11, S()。n 隐含地是 constexpr code>,并且值为 0 constexpr 表达式可以是空指针常量。

In C++11, S().n is implicitly a constexpr expression with value 0, and a constexpr expression with value 0 can be a null pointer constant.

最后,就我所知,这不是委员会的有意改变。如果你编写的代码取决于这种差异,你可能会被咬在未来如果/当委员会纠正自己。我会引导远离这个领域。使用它来赢得投注 - 而不是在生产代码。

Finally, this is not an intentional change on the part of the committee as far as I can tell. If you're writing code that depends on this difference, you may well get bitten in the future if/when the committee corrects itself. I would steer well clear of this area. Use it to win bar bets -- not in production code.

这篇关于默认构造函数,POD的初始化和C ++ 11中的隐式类型转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆