Ofe*_*lon 31 c++ decltype language-lawyer c++11
当有人问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, ...
Run Code Online (Sandbox Code Playgroud)
所以问题仍然存在。为什么括号的处理方式不同?是否有人熟悉其背后的技术论文或委员会讨论?对括号的明确考虑导致认为这不是疏忽,所以一定有我遗漏的技术原因。
小智 18
这不是疏忽。有趣的是,在Decltype 和 auto (revision 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&
Run Code Online (Sandbox Code Playgroud)
真正有趣的是它如何处理return语句:
decltype(auto) f()
{
int i{ 0 };
return (i);
}
Run Code Online (Sandbox Code Playgroud)
我的 Visual Studio 2019 建议我删除多余的括号,但实际上它们变成了decltype((i))哪些更改返回值,int&因为返回对局部变量的引用,因此它成为 UB。
Sto*_*ica 14
为什么括号的处理方式不同?
括号没有区别对待。未加括号的 id 表达式被区别对待。
当存在括号时,所有表达式的常规规则都适用。类型和值类别被提取并编码在 的类型中decltype。
有特殊规定,以便我们可以更轻松地编写有用的代码。当应用于decltype(成员)变量的名称时,我们通常不想要某种类型来表示将变量视为表达式时的属性。相反,我们只需要声明变量的类型,而不必应用大量类型特征来获取它。这正是我们decltype指定的内容。
如果我们确实关心变量作为表达式的属性,那么我们仍然可以通过一对额外的括号轻松获得它。
| 归档时间: |
|
| 查看次数: |
1182 次 |
| 最近记录: |