为什么 std::tuple 分解为右值引用

Why does std::tuple decompose into rvalue references

为什么 std::tuple 分解为右值引用?

#include <tuple>

template <typename, typename> struct same_type;
template <typename T> struct same_type<T, T> {};

void foo() {
  std::tuple tuple(1, 'a', 2.3, true);
  auto[i, c, d, b] = tuple;
  same_type<decltype(i), int &&>{};
  same_type<decltype(c), char &&>{};
  same_type<decltype(d), double &&>{};
  same_type<decltype(b), bool &&>{};
}

使用 gcc trunk 编译没有错误。 我本来希望使用普通类型,例如

same_type<decltype(i), int>{};

Live example

海湾合作委员会错误。 decltype 应用于结构化绑定 returns 引用类型 ,对于类似元组的情况,它是 std::tuple_element 返回的确切类型。换句话说,该语言在这里非常努力地隐藏这些实际上是引用的事实。

[dcl.type.simple]/4:

For an expression e, the type denoted by decltype(e) is defined as follows:

  • if e is an unparenthesized id-expression naming a structured binding ([dcl.struct.bind]), decltype(e) is the referenced type as given in the specification of the structured binding declaration;
  • [...]

[dcl.struct.bind]/3:

Otherwise, if the expression std::tuple_size<E>::value is a well-formed integral constant expression [...] Given the type Ti designated by std::tuple_element<i, E>::type, each vi is a variable of type “reference to Ti” initialized with the initializer, where the reference is an lvalue reference if the initializer is an lvalue and an rvalue reference otherwise; the referenced type is Ti.