16

私は次のタプルビジネスに少し困惑しています:

int testint = 1;
float testfloat = .1f;
std::tie( testint, testfloat ) = std::make_tuple( testint, testfloat );
std::tuple<int&, float&> test = std::make_tuple( testint, testfloat );

それは機能しstd::tieますが、参照のタプルに直接割り当ててもコンパイルされず、

「エラー: 'std::tuple<int, float>' から非スカラー型 'std::tuple<int&, float&>' への変換が要求されました」

また

「std::tuple<int, float> から std::tuple<int&, float&> への適切なユーザー定義の変換がありません」

なんで?これを行うことで、実際に割り当てられているのと同じタイプであるかどうか、コンパイラで再確認しました。

static_assert( std::is_same<decltype( std::tie( testint, testfloat ) ), std::tuple<int&, float&>>::value, "??" );

これは真と評価されます。

また、オンラインで msvc の障害であるかどうかを確認しましたが、すべてのコンパイラで同じ結果が得られました。

4

4 に答える 4

20

make_tupleとの両方tieが、引数によって返される型を推測します。ただしtie、推定された型に従って左辺値参照型make_tupleを作成し、実際のタプルを作成します。

std::tuple<int&, float&> a = std::tie( testint, testfloat );

std::tuple<int , float > b = std::make_tuple( testint, testfloat );

 

の目標は、関連付けられたオブジェクトの一時的なコピーを回避するために一時的なタプルを作成することです。悪い影響は、エントリ オブジェクトがローカルの一時的なものである場合tieはできないことです。returntie

于 2013-11-05T22:38:25.793 に答える
13

この関数は、 templatory で初期化できないの参照std::tie()のメンバーを実際に初期化します。操作は実行され、対応するオブジェクトの初期化は次のように表現されます。std::tuple<T&...>std::tuple<T&...>std::tuple<T...>std::tie()

std::tuple<int&, float&> test = 
    std::tuple<int&, float&>(testint, testfloat) = std::make_tuple(testint, testfloat);

(明らかに、通常、既にバインドされている変数の値とは異なる値を使用します)。

于 2013-11-05T22:34:53.377 に答える
1

問題は、rhsstd::make_tuple(testint, testfloat)が参照の配列を返さないことstd::tuple<int, int>です。これは、値が左辺値参照にバインドできない一時的なものです。参照のタプルが必要な場合は、ヘルパー関数を使用できますstd::ref

auto test = std::make_tuple(std::ref(a), std::ref(b));
//                          ^^^^^^^^^^^  ^^^^^^^^^^^

これと の違いtieは、参照がstd::tie(a, b)構築時に によって初期化されることです。

于 2013-11-05T22:35:42.037 に答える