2013-09-27 71 views
10

在C++ 11標準它指出(見cppreference.com,也參見標準的第20.4.2.4)它指出爲什麼std :: make_tuple將std :: reference_wrapper參數轉換爲X&?

template< class... Types > 
tuple<VTypes...> make_tuple(Types&&... args); 

創建一個元組對象,從類型推斷目標類型的論據。

對於Types...每個Ti,相應的類型ViVtypes...std::decay<Ti>::type除非的std::decay導致std::reference_wrapper<X>對於某些類型X,在這種情況下,推定的類型是X&應用。

我想知道:爲什麼參考包裝在這裏特別對待?

+0

我認爲主要的觀點是'std :: reference_wrapper'是一個傳統的標記(特殊處理),它在rvalue引用之前是必需的,請參閱http://stackoverflow.com/questions/20080493/semantics-for-wrapped-objects -reference-value-by-default-via-stdmove-stdref?rq = 1。我認爲它在C++ 11中應該是必需的,但是這個慣例依然存在。 – alfC

回答

11

這或多或少是reference_wrapper的主要用途。

通常,std::make_tuple總是讓值的元組std::decay模擬傳遞值語義)。鑑於int x, y; std::make_tuple(x, y);作出std::tuple<int, int>,即使它會推斷Types作爲一包參考int&, int&std::decay將這些轉換爲int, int

reference_wrapper可以強制的引用元組的創建:std::make_tuple(std::ref(x), y)會做出std::tuple<int&, int>

標準庫的其他部分以相同的方式使用reference_wrapper。例如,std::bind通常會將綁定的參數複製/移動到結果對象中,但如果您希望它只存儲引用,則可以通過傳遞reference_wrapper來明確請求它。

+0

請注意,這使得不可能'make_tuple'並生成包含'std :: reference_wrapper '的'tuple',但是您可以'make_tuple'並生成包含'std :: reference_wrapper &'的'tuple'。我覺得這很有趣。 – Yakk

+0

是的,但reference_wrappers元組相對於引用元組沒有什麼優勢。 –

4

您的標題是誤導性的:使用std::reference_wrapper<X>將成員變爲X&而不是X。這個轉換完成的原因是std::reference_wrapper<T>是一個輔助類型,用於將值類型轉換爲引用類型。但是,需要進行額外的轉換才能顯示這種方式,有時會干擾使用情況。因此,在可能的情況下展開參考似乎是一種合理的方法:使std::tuple<...>成員T&使用更自然。

0

人們通常使用std::reference_wrapper<X>來保存不可複製的類型。因此,在make_tuple中複製它們會超出目的(並且如果複製構造函數被刪除,可能會破壞構建)。這就是爲什麼它在返回類型中使用引用(而不是一個值)的原因。

相關問題