Um das Kernkonzept zu verdeutlichen, reduzieren wir es auf ein grundlegenderes Beispiel. Obwohl std::tie
dies für Funktionen nützlich ist, die (ein Tupel) mehr Werte zurückgeben, können wir es mit nur einem Wert gut verstehen:
int a;
std::tie(a) = std::make_tuple(24);
return a; // 24
Dinge, die wir wissen müssen, um vorwärts zu kommen:
Der nächste Schritt besteht darin, die Funktionen zu entfernen, die Ihnen nur im Weg stehen, damit wir unseren Code folgendermaßen umwandeln können:
int a;
std::tuple<int&>{a} = std::tuple<int>{24};
return a; // 24
Der nächste Schritt besteht darin, genau zu sehen, was in diesen Strukturen passiert. Dafür erstelle ich zwei Arten von T
Substituenten für std::tuple<int>
und Tr
Substituenten std::tuple<int&>
, die für unsere Operationen auf das Nötigste reduziert sind:
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
}
Und schließlich möchte ich die Strukturen alle zusammen loswerden (nun, es ist nicht 100% äquivalent, aber es ist nah genug für uns und explizit genug, um es zuzulassen):
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)
Initialisiert also im Grunde einen Datenelementverweis auf a
. std::tuple<int>(24)
Erstellt ein Datenelement mit Wert 24
, und die Zuweisung weist der Datenelementreferenz in der ersten Struktur 24 zu. Aber da dieses Datenelement eine Referenz gebunden a
, dass im Grunde Abtretungsempfänger 24
zu a
.
tuple
könnte eine Referenz enthalten sein?std::tuple
ist kein Container, zumindest nicht in der C ++ - Terminologie, nicht dasselbe wie dasstd::vector
und dergleichen. Zum Beispiel können Sie nicht mit den üblichen Methoden über ein Tupel iterieren, da es verschiedene Arten von Objekten enthält.Dies beantwortet Ihre Frage in keiner Weise, aber lassen Sie mich sie trotzdem posten, da C ++ 17 im Grunde genommen bereit ist (mit Compiler-Unterstützung). Wenn Sie sich also fragen, wie das veraltete Material funktioniert, lohnt es sich wahrscheinlich, einen Blick darauf zu werfen, wie das aktuelle und Zukünftig funktioniert auch die Version von C ++.
Mit C ++ 17 können Sie so ziemlich
std::tie
zugunsten sogenannter strukturierter Bindungen kratzen . Sie tun dasselbe (naja, nicht dasselbe , aber sie haben den gleichen Nettoeffekt), obwohl Sie weniger Zeichen eingeben müssen, keine Bibliotheksunterstützung benötigen und Sie auch die Möglichkeit haben, Referenzen zu übernehmen, wenn dies der Fall ist was du willst(Beachten Sie, dass Konstruktoren in C ++ 17 Argumente ableiten und daher
make_tuple
auch etwas überflüssig geworden sind.)quelle
tie
strukturierte Bindungen im Gegensatz zu strukturierten Bindungen auf diese Weise für Typen verwendet werden können, die nicht standardmäßig konstruierbar sind.std::tie()
ist viel weniger nützlich seit C ++ 17, wo strukturierte Bindungen normalerweise überlegen sind, aber es hat immer noch Verwendungsmöglichkeiten, einschließlich der Zuweisung zu vorhandenen (nicht gleichzeitig neu deklarierten) Variablen und der prägnanten Ausführung anderer Dinge wie dem Austausch mehrerer Variablen oder anderer Dinge, die muss Referenzen zuordnen.