请参阅以下代码(请参见实时here):
#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;
}
我希望看到输出0 0 1 1
,但GCC和clang都会输出0 1 0 1
。真的很困惑。有人能给我一个解释吗?
答案 0 :(得分:3)
查看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 )
在您的情况下,t
是一个l值,因此它返回int&& &
,后者变为int&
。
答案 1 :(得分:1)
相关的std::get
重载是:
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 );
请注意,如果参数是左值,则返回左值引用;如果参数是右值,则返回右值引用。 t
是左值,因此返回左值。