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

Confusion about the return type of std::get() on std::tuple objects

本文关键字:std 返回类型 get tuple 对象 关于      更新时间:2023-10-16

请看下面的代码(在这里看到它(:

#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。真的很困惑。有人可以给我一个解释吗?

查看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& .

相关的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 是左值,因此返回左值。