簡體   English   中英

默認構造函數,POD的初始化和C ++ 11中的隱式類型轉換

[英]Default constructors, initialization of POD and implicit type conversions in C++11

我剛看了Chandler在2012年Going Native上對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(void*) f(X) 他還指出原因是S()。n默認初始化為0,使其成為nullptr常量。

首先,我正確地假設成員變量n的零初始化是依賴於編譯器實現的並且不是由標准保證(或者用c ++ 11進行了這種改變)? 錢德勒暗示這是由於對持續表達的支持,但我仍然不能完全遵循他的推理。

其次,為什么用C ++ 03而不是c ++ 11調用f(X) 我假設f(void*)無論S().n的值是否隱式轉換為X

對於Chandler的解釋,請參閱以下鏈接,45分鍾:

Clang:從Murphy的Million Monkeys中捍衛C ++

首先,我正確地假設成員變量n的零初始化是依賴於編譯器實現的並且不是由標准保證(或者用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

其次,為什么用C ++ 03而不是c ++ 11調用f(X)? 我假設f(void *)無論S()。n的值是否隱式轉換為X,都會啟動

在C ++ 03中, int永遠不會成為空指針常量。 一旦0被輸入為int ,比如將它賦給int ,那么它永遠是一個int ,而不是一個空指針常量。

在C ++ 11, S().n是隱含一個constexpr表達值0 ,和constexpr與值表達式0可以是一個空指針常數。

最后,就我所知,這不是委員會的故意改變。 如果您正在編寫依賴於這種差異的代碼,那么如果/當委員會糾正自己時,您可能會在將來被咬。 我會很清楚這個領域。 用它來贏得賭注 - 而不是生產代碼。

首先,對C ++ 03和C ++ 11的初始化規則進行一些澄清:

// This is default construction
S s;
// s.i has undefined value

// This is initialization from a value-initialized S (C++03 rules)
S s = S();
// s.i has been zero-initialized

// This is value initialization (C++11 rules)
// new syntax, better rules, same result
S s {};
// s.i has been zero-initialized

然后,記住int不能轉換為void*所以在C ++ 03中f(S().n) 永遠不會調用void f(void*); 即使沒有其他f聲明可用。

什么可能在C ++ 03是做f(0)這將調用void f(void*); 即使void f(X); 存在。 原因是int - > X轉換(所謂的用戶定義轉換)不優於零積分常量 - > void*轉換(不是UD轉換)。 注意,也可以調用void f(void*); via f( (int()) )因為int()也是零積分常數,即使在C ++ 03中也是如此。 (像往常一樣,括號在這里解決了語法模糊性。)

C ++ 11的變化是現在S().n是零積分常數。 原因是S()現在是一個常量表達式(由於廣義常量表達式),這種成員訪問也是如此。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM