2016-03-31 8 views
2

Bitte den folgenden Code sehen (siehe es here leben):Verwirrung über die Rückkehr Art von std :: get() auf std :: Tupelobjekten

#include <iostream> 
#include <tuple> 
#include <type_traits> 
#include <utility> 

struct S { 
    int&& v; 
}; 

int main() { 
    std::tuple<int&&> t(1); 
    std::cout << std::is_same<int, decltype(std::get<0>(t))>{} << std::endl; 
    std::cout << std::is_same<int&, decltype(std::get<0>(t))>{} << std::endl; 
    std::cout << std::is_same<int&&, decltype(std::get<0>(t))>{} << std::endl; 
    S s{1}; 
    std::cout << std::is_same<int&&, decltype(s.v)>{} << std::endl; 
} 

Ich erwarte die Ausgabe 0 0 1 1, um zu sehen, aber sowohl GCC als auch clang geben den Ausgang 0 1 0 1 statt. Wirklich verwirrt. Könnte mir jemand eine Erklärung geben?

Antwort

3

Blick auf Signatur von std::get:

template< std::size_t I, class... Types > 
constexpr std::tuple_element_t<I, tuple<Types...> >& 
    get(tuple<Types...>& t) 

template< std::size_t I, class... Types > 
constexpr std::tuple_element_t<I, tuple<Types...> >&& 
    get(tuple<Types...>&& t) 

In Ihrem Fall t ist ein l-Wert, so dass es int&& & zurück, die int& wurde.

+0

Irgendwelche Ideen, warum 'std :: tuple_element <0, std :: tuple > :: type &' gibt ein 'int &' zurück Wie geht 'int &' + '&' in int & zusammen? – James

+0

@Phantom: Sehen Sie sich [Prägnante Erklärung der Referenz-Kollaps-Regeln] an (http://stackoverflow.com/questions/13725747/concise-explanation-of-reference-collapsing-rules-requested-1-aa- 2) – Jarod42

+0

Vielen Dank. Genau das habe ich gesucht. – James

1

Die relevanten std::get Überlastungen sind diese:

template< std::size_t I, class... Types > 
typename std::tuple_element<I, tuple<Types...> >::type& 
get(tuple<Types...>& t); 

template< std::size_t I, class... Types > 
typename std::tuple_element<I, tuple<Types...> >::type&& 
get(tuple<Types...>&& t); 

anzumerken, dass ein L-Wert Bezug ein L-Wert, wenn das Argument zurückgegeben wird, ist, und eine R-Wert Referenz zurückgegeben, wenn das Argument ein R-Wert ist. t ist ein Lvalue, daher wird ein Lvalue zurückgegeben.