默认构造函数,POD的初始化和C ++ 11中的隐式类型转换 [英] Default constructors, initialization of POD and implicit type conversions in 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:
推荐答案
我是正确的假设成员
变量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屋!