回答:
コアコンセプトを明確にするために、より基本的な例に減らしましょう。がstd::tie
複数の値を(タプル)を返す関数のために有用である、私たちはただ一つの値でうまくそれを理解することができます:
int a;
std::tie(a) = std::make_tuple(24);
return a; // 24
先に進むために知っておくべきこと:
std::tie
参照のタプルを作成して返します。std::tuple<int>
およびstd::tuple<int&>
は2つの完全に異なるクラスであり、それらの間には接続がありません。それ以外は、同じテンプレートから生成されたものstd::tuple
です。タプルには、operator=
さまざまなタイプ(同じ数)のタプルが受け入れられ、各メンバーはcppreferenceから個別に割り当てられます。
template< class... UTypes > tuple& operator=( const tuple<UTypes...>& other );
(3)全てのiについて、割り当て
std::get<i>(other)
にstd::get<i>(*this)
。
次のステップは、邪魔になる関数だけを取り除くことです。そのため、コードを次のように変換できます。
int a;
std::tuple<int&>{a} = std::tuple<int>{24};
return a; // 24
次のステップは、これらの構造の内部で何が起こるかを正確に確認することです。このT
ためにstd::tuple<int>
、とTr
置換基の2つのタイプの置換基を作成std::tuple<int&>
し、操作の最小限にまで削減します。
struct T { // substituent for std::tuple<int>
int x;
};
struct Tr { // substituent for std::tuple<int&>
int& xr;
auto operator=(const T& other)
{
// std::get<I>(*this) = std::get<I>(other);
xr = other.x;
}
};
auto foo()
{
int a;
Tr{a} = T{24};
return a; // 24
}
そして最後に、私はすべての構造を一緒に取り除くのが好きです(まあ、それは100%の等価ではありませんが、私たちにとっては十分に近く、それを許可するのに十分明示的です):
auto foo()
{
int a;
{ // block substituent for temporary variables
// Tr{a}
int& tr_xr = a;
// T{24}
int t_x = 24;
// = (asignement)
tr_xr = t_x;
}
return a; // 24
}
したがって、基本的にstd::tie(a)
はへのデータメンバー参照を初期化しますa
。std::tuple<int>(24)
value 24
でデータメンバーを作成し、最初の構造体のデータメンバー参照に24を割り当てます。ただし、そのデータメンバーはにバインドされた参照であるためa
、基本的にはに割り当て24
られa
ます。
std::tuple
はコンテナではありません。少なくともC ++の用語では、などとは異なりstd::vector
ます。たとえば、タプルにはさまざまなタイプのオブジェクトが含まれているため、通常の方法でタプルを反復処理することはできません。
これはどのようにもあなたの質問に答えませんが、C ++ 17は基本的に(コンパイラーのサポートにより)準備ができているので、とにかくそれを投稿させてください。将来的には、C ++のバージョンも機能します。
C ++ 17を使用するstd::tie
と、いわゆる構造化バインディングを優先してスクラッチできます。それらは同じです(まあ、同じではありませんが、同じ効果があります)。入力する文字の数は少なく、ライブラリサポートは必要ありません。また、参照が発生した場合、参照を取得することもできます。あなたが欲しいもの。
(C ++ 17では、コンストラクターが引数の演繹を行うためmake_tuple
、やや不必要になったことに注意してください。)
int a, b;
std::tie(a, b) = std::make_tuple(2, 3);
// C++17
auto [c, d] = std::make_tuple(4, 5);
auto [e, f] = std::tuple(6, 7);
std::tuple t(8,9); auto& [g, h] = t; // not possible with std::tie
tie
、とは異なり、構造化バインディングは、デフォルトで構成できないタイプに対してこの方法で使用できることにも言及する価値があります。
std::tie()
C ++ 17以降はそれほど有用ではありません。通常、構造化バインディングの方が優れていますが、既存の(同時に宣言されていない)変数への割り当てや、複数の変数の交換など、他のことを簡潔に行うなどの用途があります。参照に割り当てる必要があります。