2012-10-04 92 views
4

我需要創建std::tuple<const XYZ,...>,其中XYZ是不可複製。是甚至可能的嗎?我當前的代碼Tuple with const noncopyable element

auto test() -> std::tuple<const XYZ> { return std::make_tuple(XYZ()); } 

導致在Visual Studio 2010 ...我覺得這是我在建設有一個R值的元組相當可疑C2248,所以我認爲此舉建設會踢...

+2

[This](http://liveworkspace.org/code/cd8c16cb4e76b3602ebc37074d6238f3)用VC++ 2012編譯得很好;如果它不符合VC++ 2010,那就把它編成一個編譯器錯誤(並升級你的編譯器; - ])。 – ildjarn

+0

也許試試'std :: forward_as_tuple'作爲解決方法。 – Xeo

+0

@Xeo:糟糕,謝謝你的糾正。 – ildjarn

回答

2

您的問題是該元素是不可複製的和constconst XYZ元素表現爲const XYZ成員;通過5.2.5p4訪問在xvalue上的const XYZ元素將產生具有聯合cv限定的x值,即具有有效類型const XYZ &&。該類型不適合作爲XYZ的移動構造函數的參數,因此將嘗試調用已刪除/私有拷貝構造函數。

看它的另一種方式是,移動構造函數(例如中std::tuple<...>移動的構造函數)有責任確保其參數在未指定的離開,但有效狀態。通過創建元素const,您已經說過該元素的唯一有效狀態是它的構造狀態,所以移動構造函數不允許從其移動,即使它包含在xvalue中也是如此。

一種解決方法是定義一個常量移動構造和const_cast其參數委託給移動構造函數:

XYZ(const XYZ &&xyz): XYZ(const_cast<XYZ &&>(xyz)) {} 

有趣的是,用gcc-4.7.2這是不夠的,只是申報的const移動構造函數;通過RVO,可以省略對const移動構造函數的實際調用。不要依賴這個。

相關問題