27

考虑一个例子:

#include <iostream>
#include <type_traits>
#include <tuple>

int main() {
    auto tup = std::make_tuple(1, 2);
    auto [ a, b ] = tup;
    decltype(auto) e = a;
    std::cout << std::boolalpha << std::is_reference_v<decltype(e)> << std::endl;
}

clang (output: false) 和gcc (output: true) 在这个简单的案例中存在分歧。请记住,例如这个问答应该e是参考还是 gcc 错误?或者代码格式不正确?

4

1 回答 1

19

标识符本身就是参考。来自[dcl.struct.bind]/3

给定由 指定的类型 T istd​::​tuple_­element<i, E>​::​type,每个 vi都是使用初始化程序初始化的“对 T i引用”类型的变量,如果初始化程序是左值引用,则引用是左值引用,否则是右值引用;引用的类型是 T i

也就是说,a两者b都是int&&

decltype(auto)实际行为方式来自[dcl.type.auto.deduct]

如果占位符是decltype(auto)类型说明符,T则应单独为占位符。推导的类型T按照 [dcl.type.simple] 中的描述确定,就好像e它是decltype.

这个措辞真的很尴尬,但最终:

decltype(auto) e = a;
~~~~~~~~~~~~~~

方法:

decltype( a  ) e = a;
         ~~~~

并且decltype(a)意味着,来自[dcl.type.simple]/4.1

ife是命名结构化绑定 ([dcl.struct.bind])的无括号id 表达式decltype(e),是结构化绑定声明规范中给出的引用类型;

引用类型是,所以必须a是。这意味着它不是参考,并且 clang 是正确的。归档81176inteint

于 2017-06-22T13:49:12.297 回答