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

C++ 为什么decltype(auto)在这里返回引用?,c++,auto,c++14,decltype,C++,Auto,C++14,Decltype,我想我理解自动编码。关于decltype也一样。然而,在C++14中,可以使用一些可怕的东西,如decltype(auto)作为函数的返回类型。考虑以下事项: decltype(auto) foo() { int m = 1; return m; } 返回类型为int,一切都有意义 但是, decltype(auto) foo() { int m = 1; return (m); } 返回int&(即引用int) 我完全不知道为什么会发生这种情况,为什么这些括

我想我理解自动编码。关于
decltype
也一样。然而,在C++14中,可以使用一些可怕的东西,如
decltype(auto)
作为函数的返回类型。考虑以下事项:

decltype(auto) foo()
{
    int m = 1;
    return m;
}
返回类型为
int
,一切都有意义

但是,

decltype(auto) foo()
{
    int m = 1;
    return (m);
}
返回
int&
(即引用
int

我完全不知道为什么会发生这种情况,为什么这些括号会有任何区别!?希望有人能对此有所启发


PS:我还使用了
C++
标记,因为检查
C++
标记的人比检查
C++14
标记的人多得多

  • 对于表达式e,decltype(e)表示的类型定义如下:
    -如果e是一个未授权的id表达式或未授权的类成员访问(5.2.5),decltype(e)是由e命名的实体的类型。如果没有这样的实体,或者如果e命名了一组重载函数,则程序的格式不正确
    -否则,如果e是xvalue,decltype(e)是T&&,其中T是e的类型
    -否则,如果e是左值,decltype(e)是T&,其中T是e的类型
    -否则,decltype(e)就是e的类型
    在您的示例中,您有
    返回(m)
    ,因此
    e
    (m)
    。这不是一个未被解析的id表达式或类成员访问,所以我们转到第二个项目符号。它不是一个x值,所以我们转到第三个项目符号。它是一个左值,所以类型是
    T&
    ,其中
    T
    int

    ,因为
    decltype((m))
    也是一个左值引用。我想是的,所以在它周围加上括号就是左值了?也就是说,如果我返回(Foo()),它是否被视为返回对
    Foo()
    的引用?@vsoftco no,
    decltype(e)
    的规则取决于
    e
    是否被括号括起来。这并不意味着在其他地方添加括号会产生这种效果。规则说,空标识符不会产生左值,但任何其他左值表达式都会产生。因此,在一个空标识符周围加上括号会将其转换为一个“其他”左值表达式
    Foo()
    不是一个简单的标识符,所以paren没有区别。@kek,谢谢,我知道现在发生了什么。事实上,我唯一不明白的是为什么Puting
    (…)
    使
    decltype
    认为它有左值
    m
    已经是左值,而
    (m)
    也是左值。关键是括号改变了
    decltype
    使其推断类型的方式。如果没有双括号,您只会得到
    m
    的类型,使用双括号,您会得到T&&或T&这取决于
    m
    是左值还是右值(在您的示例中,它是左值),我不知道的是为什么(它启用了什么功能,否则就不可能了?)。当然有一个合乎逻辑的解释,我想了解更多(关于这篇文章的推文目前正在大量转发,很多人可能也感兴趣)。我为
    decltype(e)
    引用的规则在C++11中已经存在,因此
    decltype(auto)
    规则在一致性方面是相同的(请参阅:“我突然想到,
    decltype
    的含义根据表达式的形式(例如,括号或不括号)的不同,在这种情况下可能更令人惊讶,但我认为如果这与C++11
    decltype
    的工作方式不同,那将更令人惊讶。”C++11规则是在年引入的,本质上没有解释,它允许对decltype进行两种不同的查询,询问“如果这个变量是什么类型”或“这个表达式的类型和值类别(左值/右值)是什么”。括号外是后者的语法。