【问题标题】:Confusion about the return type of std::get() on std::tuple objects关于 std::tuple 对象上 std::get() 的返回类型的混淆
【发布时间】:2016-07-19 13:08:45
【问题描述】:

请看下面的代码(看直播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。真的很迷茫。谁能给我一个解释?

【问题讨论】:

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


    【解决方案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 是一个左值,所以它返回 int&amp;&amp; &amp;,它变成了int&amp;

    【讨论】:

    【解决方案2】:

    相关的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 是一个左值,所以返回一个左值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-15
      • 1970-01-01
      • 2019-09-10
      • 2011-06-20
      • 2020-07-07
      • 1970-01-01
      • 1970-01-01
      • 2021-10-16
      相关资源
      最近更新 更多