2015-02-06 60 views
3

在C++ 11中初始化一個常量數據成員,例如類型爲int的常量數據成員時,執行以下四種不同的語法是否會做同樣的事情?如果不是,有什麼區別?C++中的語義差異,定義一個常量數據實例

{ 
    const int a = 5; //usual initialization, "=" is not assignment operator here it is an initialization operator. 
} 
{ 
    const int a(5); //calling the constructor function directly 
} 
{ 
    const int a = {5}; //similar to initializing an array 
} 
{ 
    const int a{5}; //it should work, but visual studio does not recognizing it 
} 

爲什麼第四個不被Visual Studio識別爲有效語句?

+0

沒關係,我使用的Visual Studio 2012和正在以下錯誤: '1錯誤C2734: 'A':const對象必須如果不是的extern初始化':一個 ' 「2-錯誤C2601':局部函數定義是非法的' '3 - 這一行包含一個'{'尚未匹配' – 2015-02-06 06:16:08

回答

7

它們在Visual Studio 2013中都是有效的和相同的(最後一個在VS2012中無效,因爲建議使用@remyabel)。

兩個{...}語法可以在什麼構造函數被調用某一類型的人不同,但類型int不使用構造

他們將不同時,構造一個類,接受std::initializer_list<T>

舉個例子來說,這個構造有 - 以某種形式 - 始終是std::vector

explicit vector(size_type count ...); 

一個組成部分,這是一個加在C++ 11

vector(std::initializer_list<T> init, const Allocator& alloc = Allocator()); 

這裏,vector<int>(5)將調用第一個構造函數,並創建一個向量大小5.

vector<int>{5}將調用第二個並創建一個向量單e 5

+0

你是什麼意思的「任何int」?該語法僅適用於int嗎? – 2015-02-06 06:12:17

+0

但'int'有一個構造函數。你可以使用'int()'來調用它,並且它被定義爲創建一個零初始化的標量。也作爲一個練習'new int()'總是產生一個零新的int,但是'new int'產生一個未初始化的int。 – 2015-02-06 06:13:49

+2

@ v.oddou初始化規則控制不同類型的對象,包括類類型。一個'int'不是一個類的類型。 – 2015-02-06 06:15:50

4

在C++ 03這些是等效

const int a = 3; 
const int a(3); 

在C++ 11均勻初始化語法被引入,從而

const int a{3}; 
const int a = {3}; 

是允許的,是等價的。但是,前兩個和後兩個在所有情況下都不相同。 {}不允許縮小。例如

int abc = {12.3f}; 
int xyz(12.3f); 

下面是GCC說

error: type 'float' cannot be narrowed to 'int' in initializer list [-Wc++11-narrowing]

int abc = {12.3f}; 
      ^~~~~ 

warning: implicit conversion from 'float' to 'int' changes value from 12.3 to 12 [-Wliteral-conversion]

int abc = {12.3f}; 
      ~^~~~~ 

所以前者而產生了錯誤,而後者只是一個警告。

注意事項在統一初始化語法:如果a是一種接受std::initializer_list的對象,然後const MyClass a = { 1 }將意味着你使用的構造函數,而不是採取構造一個int即使它是可用的(在解釋德魯的飲料);如果你想選擇其他構造函數,那麼你必須使用()語法。如果a是一個數組,那麼你正在使用聚合初始化。

See here用於C++中提供的各種初始化選項。

0

編碼風格最終是主觀的,它是不太可能會從中獲得實質性的好處。但是,我要說的是,你從自由使用統一初始化中獲益:

所有4個語句都是有效的,它們是相同的。

const int a = 5; - >不管怎樣,是正常的初始化語法。 不需要解釋。

const int a(5); - >功能型初始化

const int a = {5}; - >數組類型初始化

const int a{5}; - >這不是在Visual Studio 2012允許的,但是,初始化列表的支持在Visual Studio 2013年因此被添加const int a {5},可以很好地編譯VS2013中的任何問題。

但是,
你放棄的唯一真正的力量正在縮小。您無法使用初始化一致的較大值初始化較小的值。

int val{5.5}; 

這將不會編譯。你可以用老式的初始化來做到這一點,但不是統一的初始化。