【问题标题】:Why does decltype(auto) return a reference here?为什么 decltype(auto) 在这里返回一个引用?
【发布时间】:2015-02-17 21:03:10
【问题描述】:

我想(想)我理解autodecltype 也一样。但是,在 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 多得多。

【问题讨论】:

  • 因为decltype((m)) 也是一个左值引用。
  • 我是这么认为的,所以把括号放在周围使它成为左值?即,如果我执行return (Foo()),是否会被视为返回对Foo() 的引用?
  • @vsoftco 不,decltype(e) 的规则取决于 e 是否带括号。这并不意味着在别处添加括号会有这种效果
  • 规则说裸标识符不会产生左值,但任何其他左值表达式都会产生。因此,在裸标识符周围加上括号会将其变成“其他”左值表达式。 Foo() 不是一个裸标识符,所以括号没有区别。
  • @kek,谢谢,我明白现在发生了什么。

标签: c++ auto c++14 decltype


【解决方案1】:

7.1.6.2 [dcl.type.simple]

  1. 对于表达式 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 的类型。

在您的示例中,您有return (m),所以e(m)。这不是无括号的 id 表达式或类成员访问,所以我们转到第二个项目符号。它不是一个 xvalue,所以我们转到第三个项目符号。它是一个左值,所以类型是T&,其中Tint

【讨论】:

  • 正确,我唯一不明白的是为什么把(...)decltype 认为它有一个左值
  • m 已经是左值,(m) 也是左值。关键是括号改变了decltype 推断类型的方式。如果没有双括号,您只会得到 m 的类型,使用双括号,您会得到 T&& 或 T&,具体取决于 m 是左值还是右值(在您的示例中,它是左值)
  • 我不明白的是 why (它有什么作用,否则不可能实现?)。肯定有一个合乎逻辑的解释,我有兴趣了解更多相关信息(关于这篇文章的推文目前正在被大量转发,因此可能会有很多人感兴趣)。
  • 我为 decltype(e) 引用的规则在 C++11 中已经存在,所以 decltype(auto) 规则在一致性方面是相同的(参见 N3638: decltype 的含义取决于表达式的形式(例如是否带括号)在这种情况下可能更令人惊讶,但我认为如果它与 C++11 decltype 的工作方式不同会更令人惊讶。”) C++11规则在N2115中引入,不做解释
  • 本质上它允许使用 decltype 进行两个不同的查询,询问“如果这个变量是什么类型”或“这个表达式的类型和值类别(左值/右值)是什么” .额外的括号是后者的语法。
猜你喜欢
  • 2014-10-08
  • 2021-11-18
  • 1970-01-01
  • 2017-03-18
  • 2014-02-17
  • 2015-03-02
  • 1970-01-01
  • 2017-08-02
相关资源
最近更新 更多