关于std :: tuple对象上std :: get()的返回类型的混淆

时间:2016-03-31 07:53:21

标签: c++ c++11 tuples language-lawyer decltype

请参阅以下代码(请参见实时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。真的很困惑。有人能给我一个解释吗?

2 个答案:

答案 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是左值,因此返回左值。

相关问题