Aby wyjaśnić podstawową koncepcję, sprowadzimy ją do bardziej podstawowego przykładu. Chociaż std::tie
jest to przydatne w przypadku funkcji zwracających (krotkę) więcej wartości, możemy to zrozumieć, mając tylko jedną wartość:
int a;
std::tie(a) = std::make_tuple(24);
return a; // 24
Rzeczy, które musimy wiedzieć, aby iść naprzód:
Następnym krokiem jest pozbycie się tych funkcji, które tylko przeszkadzają, abyśmy mogli przekształcić nasz kod do tego:
int a;
std::tuple<int&>{a} = std::tuple<int>{24};
return a; // 24
Następnym krokiem jest sprawdzenie, co dokładnie dzieje się wewnątrz tych struktur. W tym celu tworzę 2 typy T
podstawników std::tuple<int>
i Tr
podstawników std::tuple<int&>
, zredukowane do minimum dla naszych operacji:
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
}
I wreszcie, lubię pozbywać się wszystkich struktur razem (cóż, nie jest to w 100% równoważne, ale jest wystarczająco blisko dla nas i wystarczająco wyraźne, aby na to pozwolić):
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
}
Zasadniczo std::tie(a)
inicjalizuje odwołanie do elementu członkowskiego danych a
. std::tuple<int>(24)
tworzy element danych z wartością 24
, a przypisanie przypisuje 24 do odniesienia do elementu danych w pierwszej strukturze. Ale ponieważ ten element członkowski danych jest powiązanym odniesieniem a
, w zasadzie przypisuje się 24
do a
.
tuple
miałbym mieć odniesienie?std::tuple
nie jest kontenerem, przynajmniej nie w terminologii C ++, nie jest tym samym, costd::vector
lubi i. Na przykład nie możesz iterować zwykłymi sposobami po krotce, ponieważ zawiera ona różne typy obiektów.To w żaden sposób nie odpowiada na twoje pytanie, ale mimo wszystko pozwól, że napiszę, ponieważ C ++ 17 jest w zasadzie gotowy (z obsługą kompilatora), więc zastanawiając się, jak działają przestarzałe rzeczy, prawdopodobnie warto przyjrzeć się, jak bieżący, i przyszła wersja C ++ też działa.
W C ++ 17 możesz w dużym stopniu odciąć się
std::tie
od tego, co nazywa się powiązaniami strukturalnymi . Robią to samo (no cóż, nie to samo , ale mają ten sam efekt netto), chociaż musisz wpisać mniej znaków, nie wymaga to obsługi biblioteki, a także masz możliwość pobierania referencji, jeśli tak się stanie czego chcesz.(Zwróć uwagę, że w C ++ 17 konstruktory wykonują dedukcję argumentów, więc
make_tuple
również stały się zbyteczne).źródło
tie
powiązań strukturalnych można używać w ten sposób na typach, których nie można konstruować domyślnie.std::tie()
jest znacznie mniej przydatny od czasu C ++ 17, gdzie powiązania strukturalne są zwykle lepsze, ale nadal ma zastosowania, w tym przypisywanie do istniejących (nie jednocześnie nowo zadeklarowanych) zmiennych i zwięzłe wykonywanie innych rzeczy, takich jak zamiana wielu zmiennych lub inne rzeczy, które należy przypisać do odniesień.