2013-10-03 22 views
4

當我將一些C++ 98代碼更新到C++ 11時,我注意到統一初始化並不那麼統一。其中一些與像void這樣的不完整類型有關,而其他則與pod有關。例如對於普通可複製類型,當初始化涉及複製/移動構造函數時,統一初始化不適用於直接初始化或複製初始化。爲什麼有些類型不能使用統一的初始化語法?

例如

template<class T> 
T foo() { return T("Hello World");} 
foo<void>(); 
foo<std::string>(); 
-------- 
template<class T> 
T foo() { return T{"Hello World"};} 
foo<void>(); 
foo<std::string>(); 

雖然第一部分編譯,下半年失敗error: compound literal of non-object type 'void'

struct pod { int x;int y;}; 
pod p{1,2}; //ok pod p(1,2) is error as usual 
pod p2(p); 

struct foo 
{ 
    foo(foo const& rhs) : p_(rhs.p_){} 
    pod p_; 
}; 
-------- 
struct pod { int x;int y;}; 
pod p{1,2}; 
pod p2{p}; 

struct foo 
{ 
    foo(foo const& rhs) : p_{rhs.p_}{} 
    pod p_; 
}; 

這裏也,下半年的拷貝構造與error: cannot convert 'pod' to 'int' in initialization失敗。但我認爲,這pod類是一個簡單的類型(或者甚至可以是平凡複製的類型)在C + + 11,但問題仍然存在相同除了基本類型

注:

而以下工作,

struct conv 
{ 
    operator int()const { return 1;} 
}; 
pod p{1,2}; 
pod p2{conv{}}; 

這不,

struct conv 
{ 
    operator pod()const { return pod{1,2};} 
}; 
pod p{1,2}; 
pod p2{conv{}}; 

我也注意到數組c確實與工作統一初始化,但不能使用複製/移動構造函數。但是這可能是由於數組是一個沒有複製/移動構造函數或賦值的聚合。雖然我不知道爲什麼在C++ 11中這些語法不被允許(特別是當它們是類成員時,隱式複製/移動完全是這樣)。因此,爲什麼我不能盲目地將所有的C++ 98初始化改爲C++ 11風格的統一初始化(嗯,除了有初始化器列表的類型!)?

我使用GCC 4.8.1

+2

「*我注意到統一的初始化並不那麼統一。」「你是對的,我完全不同意。 –

回答

4

「統一初始化」是這是在其提案階段使用稍顯遺憾的是在推廣初始化列表功能的非格式條款。

不,你不能在任何地方使用它。根據我的經驗,最好將其限制在

  • 聚集體(無構造函數,C++ 98已經允許這一點,但C++ 11擴展支持)的值
  • 序列(initializer_list
  • return表達式調用非顯式構造

盲目改變一切,並希望沒有語義的變化僅僅是辯論[廣告novitatem - 做的事情,因爲它是新的,不同的,而不是因爲它是適當的。

至於泛型編程,是的,很難正確支持跨越上述類別的情況。發佈具體的投訴到http://isocpp.org的留言板,也許負責語言的人將努力恢復「統一初始化」應該改進的通用順序,而不是加重:v)。

相關問題