C++decltype和圆括号-为什么

C++ decltype and parentheses - why?

本文关键字:为什么 圆括号 C++decltype      更新时间:2023-10-16

前面讨论过这个主题,但这不是重复的。

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

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

  • (表达式(
  • id表达式

更重要的是,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, ...

因此,问题依然存在为什么括号被区别对待?有人熟悉技术文件或其背后的委员会讨论吗?对括号的明确考虑导致人们认为这不是疏忽,所以我遗漏了一定有技术原因。

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

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

但在Decltype(修订版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,因为返回了对局部变量的引用。

为什么括号被区别对待?

括号没有区别对待。这是被区别对待的未加括号的本我表达。

如果存在括号,则适用所有表达式的正则规则。类型和值类别被提取并编码在decltype的类型中。

那里有特殊条款,这样我们就可以更容易地编写有用的代码。当将decltype应用于(成员(变量的名称时,我们通常不希望使用某种类型来表示作为表达式处理的变量的属性。相反,我们只需要声明变量的类型,而不必应用大量的类型特征。这正是decltype指定给我们的。

如果我们确实关心变量作为表达式的属性,那么我们仍然可以很容易地获得它,只需多加一对括号。

在C++11之前,语言需要工具来获得两种不同类型的信息

  • 表达式的类型
  • 变量声明时的类型

由于这些信息的性质,必须在语言中添加这些功能(这不能在库中完成(。这意味着新的关键字。该标准本可以为此引入两个新的关键字。例如,exprtype获取表达式的类型,decltype获取变量的声明类型。这将是一个明确而愉快的选择。

然而,标准委员会总是尽最大努力避免在语言中引入新的关键字,以最大限度地减少旧代码的破坏。向后兼容性是语言的核心哲学。

因此,在C++11中,我们只得到了一个用于两种不同事物的关键字:decltype。区分这两种用途的方法是对decltype(id-expression)进行不同的处理。这是委员会有意识的决定,是一个(小(妥协。