tuple
w podbiciu i TR1/C++ 0x zapewnia wygodną (dla pisarza funkcji) metodę zwracania dwóch wartości z funkcji - jednak wydaje się, że uszkodzenie jednego główną cechą języka do rozmówcy: zdolność do po prostu użyć funkcji zainicjować zmienną:Sposób inicjalizacji z wieloma wartościami zwracanymi w C++ (0x)
T happy();
const auto meaningful_name(happy()); // RVO means no excess copies
ale dla:
tuple<T,U> sad();
nie mamy się poddać możliwość wybrać znacząca nazwa dla naszych wartości zwracanych i użyj get<n>()
wszędzie:
const auto two_unrelated_things(sad());
lub dokonać tymczasowej:
const auto unwanted_named_temporary(sad());
const auto one_name(get<0>(unwanted_named_temporary));
const auto two_name(get<1>(unwanted_named_temporary));
lub przełączyć się z inicjalizacji do cesji, która działa tylko wtedy, gdy typy są przypisane, i łamie auto
:
tuple_element<0, decltype(sad())>::type one_mutable; // there might be a less
tuple_element<1, decltype(sad())>::type two_mutable; // verbose way
tie(one_mutable,two_mutable) = sad();
lub zrób coś nienaturalnego dla lokalnej klasy:
const struct ugh {
ugh(decltype(sad()) rhs) : one_name(get<0>(rhs)), two_name(get<1>(rhs)) {}
const tuple_element<0, decltype(sad())>::type one_name;
const tuple_element<1, decltype(sad())>::type two_name;
} stuff(sad()); // at least we avoid the temporary and get initialization
Czy istnieje lepszy sposób? Używam powyższych konstruktów kompatybilnych z VC10, czy cokolwiek w pełnym C++ 0x lub wspomaganie?
Idealnie byłoby:
- pozwala mi używać inicjalizacji nie tylko zadanie
- niech rozmówca wybierać imiona dla zwróconych-do zmiennych
- nie wprowadzać dodatkowych kopii
- działa zarówno dla zmiennych stosowych, jak i dla członków klasy:
- może być dużą biblioteką szalonych szablonów, ale ma rozsądną składnię dla pisarza wywołującego i funkcji
Interesujące pytanie, chociaż nie widzę sposobu, w jaki można zdefiniować zmienne różnych typów w pojedynczym wyrażeniu. - Myślę, że opcja "lub uczyń tymczasową" może być OK, jeśli zmienione zmienne zostaną zmienione na odniesienia (unikanie kopiowania). – UncleBens
Dobra uwaga odnośnie referencji - myślę, że to jest rozwiązanie dla zmiennych stosu. Próbowałem robić to samo w klasie: class c { publicznego: C (O) SR (SAD()), jeden (dostać <0> (SR)), dwa (dostać <1> (SR)) {} const T & one; const U & two; interent: tuple sr; } Ale wygląda na to, że w VC10, C jest o dwa wskaźniki większe od krotki, a nie wielka sprawa, ale rodzaj kulawy - czy kompilator nie uznałby legalności za odwołania i alokowanie przestrzeni w przypadku dla nich? Czy to właśnie dlatego wskaźniki do referencji są w pierwszej kolejności nielegalne? –
BCoates
W przypadku klasy, jeśli dane są przechowywane jako krotka, można po prostu podać nazwane metody dostępu, które wywołują odpowiednie 'get'. Wątpię, czy pojawi się rozwiązanie oparte na "szalonym szablonie", ponieważ podstawowy język po prostu nie wspiera tego, o co prosisz. Być może po prostu zmniejszysz liczbę znaków, które musisz wpisać za pomocą makr ... –
UncleBens