为什么decltype(auto)会在这里返回引用?

vso*_*tco 25 c++ decltype auto c++14

我想(想)我明白了auto.同样的decltype.但是,在C++ 14中,可以有一些像decltype(auto)生成函数的返回类型那样的代数.考虑以下:

decltype(auto) foo()
{
    int m = 1;
    return m;
}
Run Code Online (Sandbox Code Playgroud)

返回类型是int,一切都有意义.

然而,

decltype(auto) foo()
{
    int m = 1;
    return (m);
}
Run Code Online (Sandbox Code Playgroud)

返回int&(即引用int).

我绝对没有想到为什么会发生这种情况,为什么这些括号根本没有任何区别!?希望有人可以对此有所了解.

PS:我也标记过,C++因为有更多的人检查C++标签C++14.

Jon*_*ely 31

7.1.6.2 [dcl.type.simple]

  1. 对于表达式e,由decltype(e)表示的类型定义如下:
    - 如果e是未加密的id-expression或未加密的类成员访问(5.2.5),则decltype(e)是名为的实体的类型通过e.如果没有这样的实体,或者如果e命名了一组重载函数,那么该程序就会形成错误;
    - 否则,如果e是x值,则decltype(e)是T &&,其中T是e的类型;
    - 否则,如果e是左值,则decltype(e)是T&,其中T是e的类型;
    - 否则,decltype(e)是e的类型.

在您的例子中,你有return (m)这样e(m).这不是一个没有特写的id-expression或类成员访问,所以我们转到第二个项目符号.它不是xvalue所以我们去第三个子弹.这是一个左值,所以该类型是T&哪里Tint.

  • `m`已经是左值,而`(m)`也是左值.关键在于括号改变了`decltype`如何使其推断出类型.如果没有双括号,你只得到`m`的类型,双括号你得到T &&或T&取决于`m`是左值还是左值(在你的例子中它是左值) (4认同)
  • 我没有得到的是*为什么*(它能做什么,否则不可能?).这肯定是一个合乎逻辑的解释,我有兴趣了解它的更多信息(关于这篇文章的推文目前正在大规模转发,所以很多人可能也会感兴趣). (4认同)
  • 实质上,它允许使用decltype进行两个不同的查询,询问"如果此变量是什么类型"或"此表达式的类型和值类别(左值/右值)是什么".额外的括号是后者的语法. (4认同)
  • 我为 `decltype(e)` 引用的规则在 C++11 中已经存在,所以 `decltype(auto)` 规则是相同的以保持一致性(参见 [N3638](http://www.open-std.org) /jtc1/sc22/wg21/docs/papers/2013/n3638.html):“我突然想到,`decltype` 的含义取决于表达式的形式(例如括号与否)可能更令人惊讶这个上下文,但我认为如果它与 C++11 `decltype` 不同,它会更令人惊讶。”)C++11 规则是在 [N2115](http://www.open-std. org/jtc1/sc22/wg21/docs/papers/2006/n2115.pdf),不作解释 (2认同)