从 C++14 开始,它们通常是。
C++14 添加了一个边缘情况,其中返回值周围的括号可能会改变语义。这段代码 sn-p 显示了两个正在声明的函数。唯一的区别是返回值周围的括号。
int var1 = 42;
decltype(auto) func1() { return var1; } // return type is int, same as decltype(var1)
decltype(auto) func1() { return(var1); } // return type is int&, same as decltype((var1))
在第一个 func1 返回一个 int ,在第二个 func1 返回一个 int& 。 语义上的差异与周围的括号直接相关。
最新形式的 auto 说明符是在 C++11 中引入的。在C++ Language Spec 中描述为:
指定正在声明的变量的类型将自动
从它的初始化器推导出来。对于函数,指定返回类型是尾随
返回类型 or 将从其返回语句中推导出来(C++14 起)
C++11 还引入了 decltype 说明符,在 C++ Language Spec 中进行了描述:
检查实体的声明类型或查询表达式的返回类型。
[剪辑]
如果参数是对象/函数的无括号名称,或者是成员访问表达式(object.member 或指针->member),则 decltype 指定由此指定的实体的声明类型表达。
-
如果参数是 T 类型的任何其他表达式,则
a) 如果表达式的值类别为xvalue,则decltype指定T&&
b) 如果表达式的值类别为左值,则decltype指定T&
c) 否则,decltype 指定 T
[剪辑]
注意,如果一个对象的名字被括号括起来,它就变成了一个左值表达式,因此 decltype(arg) 和 decltype((arg)) 通常是不同的类型。
在 C++14 中,函数返回类型允许使用 decltype(auto)。原始示例是带括号的语义差异发挥作用的地方。重温原来的例子:
int var1 = 42;
decltype(auto) func1() { return var1; } // return type is int, same as decltype(var1)
decltype(auto) func1() { return(var1); } // return type is int&, same as decltype((var1))
decltype(auto) 允许从 return 语句上的实体/表达式推导出函数中的尾随返回类型。在第一个版本中,return var1; 实际上与返回类型 decltype(var1) 相同(上面规则 1 的 int 返回类型),在第二种情况下 return (var1); 它实际上与 decltype((var1)) 相同(@987654338 @ 规则 2b) 的返回类型。
括号使返回类型为int& 而不是int,因此语义发生了变化。 故事的寓意 - “并非所有返回类型上的括号都是平等的”