2014-09-03 35 views
7

我在想如果initializer_list<T>要求T有賦值運算符。下面initializer_list <T> T上的賦值運算符要求

struct Foo 
{ 
    Foo& operator=(const Foo&) = delete; 
}; 

std::vector<Foo> f = { Foo(), Foo() }; 

上編譯鐺3.4.2但有"error C2280: 'Foo &Foo::operator =(const Foo &)' : attempting to reference a deleted function"失敗視覺Studo 2013。我假設clang在這裏是正確的,但是想要檢查T是否可以被賦值。

回答

6

std::initializer_list<T>不需要T可以以任何方式分配,因爲複製std::initializer_list對象很淺 - 它不復制底層數據。

由於MSVC 2013(及以下版本)不支持自動生成移動構造函數和移動賦值運算符,您會看到錯誤。所以錯誤實際上來自std::vector試圖從初始化列表複製,而不是從初始化列表本身。

它仍然是爲什麼錯誤被觸發,因爲std::vector構造採取std::initializer_list一個問題只需要類型爲EmplaceConstructible並可能MoveInsertable,無論它的使用分配。

+0

非常有趣,當你說「自動生成移動構造函數」時,你的意思是在std :: initializer_list本身或T類型中。我試圖Fooas如下結構的Foo { 美孚(){} 美孚(常量富&){} 美孚(美孚&&){} 美孚運算符=(const的富&)=刪除; Foo&operator =(Foo &&)= delete; }; – goneskiing 2014-09-03 12:12:03

+0

@goneskiing我的意思是'Foo'類型(真的是任何用戶定義的類類型)。當然,它也適用於'std :: initializer_list',但作爲庫作者,他們可以通過明確定義移動操作來解決它。不是他們需要;正如我所說的,'std :: initializer_list'是一個淺層包裝(內部可能只是兩個指針)。 – Angew 2014-09-03 12:16:33

+0

所以當我明確地將一個移動構造函數添加到Foo中時,我仍然得到一個錯誤,我認爲這意味着VS 2013的initilizer_list被搞砸了。我確實嘗試了VS 14 CTP 3,並且與原始Foo – goneskiing 2014-09-03 12:20:14