结构化绑定的 decltype(auto) 应该是参考吗?
Is decltype(auto) for a structured binding supposed to be a reference?
考虑一个例子:
#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
) and gcc (output: true
) are disagreeing in this simple case. Having in mind e.g. e
应该是参考还是 gcc 错误?或者代码格式不正确?
标识符 本身 是引用。来自 [dcl.struct.bind]/3:
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.
即a
和b
都是int&&
.
但是 decltype(auto)
的实际行为方式来自 [dcl.type.auto.deduct]:
If the placeholder is the decltype(auto)
type-specifier, T
shall be the placeholder alone. The type deduced for T
is determined as described in [dcl.type.simple], as though e
had been the operand of the decltype
.
这个写法真是别扭,不过归根结底:
decltype(auto) e = a;
~~~~~~~~~~~~~~
表示:
decltype( a ) e = a;
~~~~
和decltype(a)
的意思是,从[dcl.type.simple]/4.1:
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;
a
的 引用类型 是 int
,因此 e
必须是 int
。这意味着它不是参考,而且 clang 是正确的。归档 81176.
考虑一个例子:
#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
) and gcc (output: true
) are disagreeing in this simple case. Having in mind e.g. e
应该是参考还是 gcc 错误?或者代码格式不正确?
标识符 本身 是引用。来自 [dcl.struct.bind]/3:
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.
即a
和b
都是int&&
.
但是 decltype(auto)
的实际行为方式来自 [dcl.type.auto.deduct]:
If the placeholder is the
decltype(auto)
type-specifier,T
shall be the placeholder alone. The type deduced forT
is determined as described in [dcl.type.simple], as thoughe
had been the operand of thedecltype
.
这个写法真是别扭,不过归根结底:
decltype(auto) e = a;
~~~~~~~~~~~~~~
表示:
decltype( a ) e = a;
~~~~
和decltype(a)
的意思是,从[dcl.type.simple]/4.1:
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;
a
的 引用类型 是 int
,因此 e
必须是 int
。这意味着它不是参考,而且 clang 是正确的。归档 81176.