首页 > 解决方案 > C++ decltype 和括号 - 为什么?

问题描述

该主题之前已讨论 ,但这不是重复的。

当有人询问 和 之间的区别decltype(a)decltype((a)),通常的答案是 -a是一个变量,(a)是一个表达式。我觉得这个答案不令人满意。

首先,a也是一种表达方式。主要表达的选项包括:

更重要的是,decltype 的措辞非常非常明确地考虑了括号

For an expression e, the type denoted by decltype(e) is defined as follows:
(1.1)  if e is an unparenthesized id-expression naming a structured binding, ...
(1.2)  otherwise, if e is an unparenthesized id-expression naming a non-type template-parameter, ...
(1.3)  otherwise, if e is an unparenthesized id-expression or an unparenthesized class member access, ...
(1.4)  otherwise, ...

所以问题仍然存在。为什么括号的处理方式不同?是否有人熟悉其背后的技术论文或委员会讨论?对括号的明确考虑导致认为这不是疏忽,所以一定有我遗漏的技术原因。

标签: c++c++11language-lawyerdecltype

解决方案


这不是疏忽。有趣的是,在Decltype 和 auto (revision 4) (N1705=04-0145)中有一个声明:

decltype 规则现在明确声明decltype((e)) == decltype(e)(如 EWG 所建议)。

但是在Decltype (revision 6):建议的措辞 (N2115=06-018)中,其中一项更改是

decltype 内的括号表达式不被视为id-expression.

措辞没有任何理由,但我认为这是 decltype 的一种扩展,使用了一些不同的语法,换句话说,它旨在区分这些情况。

C++draft9.2.8.4 中显示了它的用法:

const int&& foo();
int i;
struct A { double x; };
const A* a = new A();
decltype(foo()) x1 = 17;        // type is const int&&
decltype(i) x2;                 // type is int
decltype(a->x) x3;              // type is double
decltype((a->x)) x4 = x3;       // type is const double&

真正有趣的是它如何与return语句一起使用:

decltype(auto) f()
{
    int i{ 0 };
    return (i);
}

我的 Visual Studio 2019 建议我删除多余的括号,但实际上它们变成了decltype((i))哪些更改返回值,int&这使它成为 UB,因为返回对局部变量的引用。


推荐阅读