【问题标题】:What is the rationale behind decltype behavior?decltype 行为背后的基本原理是什么?
【发布时间】:2017-03-09 23:46:50
【问题描述】:

正如我在 C++11 中所理解的那样,decltype(expression) 用于推断给定表达式的完全相同的类型。但是当表达式本身放在括号中时,推导类型是表达式类型的左值引用。例如:

int x;
decltype(x) y = x;

相当于int y = x;,但是,

int x;
decltype((x)) y = x;

相当于int& y = x;

分别

 decltype(auto) f1()
 {
   int x = 0;
   return x; // decltype(x) is int, so f1 returns int
 }

但是

 decltype(auto) f2()
 {
   int x = 0;
   return (x); // decltype((x)) is int&, so f2 returns int&
 }

标准委员会选择这种行为的理由是什么?

后记:

现在我观察到,至少在 GCC 6.2 实现的情况下,当括号中的表达式更复杂时,例如decltype((x + x)),推导的类型是T,但不是T& .这更令人困惑。我不知道这种行为是否标准。

【问题讨论】:

  • 好吧,他们需要一些方法来让 decltype 能够产生一个参考。所以他们只是滚动随机语法骰子来得出括号。
  • @TartanLlama,decltype(auto) 出现在c++14,而decltype 规范是这样的,因为c++11,这对我来说似乎不是原因。
  • 老实说,这对我来说感觉很自然。 decltype(identifier) 是标识符的类型。如果它是一个非 id 表达式,那么它是 T& 如果它是一个左值,因为这就是 C++ 所说的“左值指定其他东西”
  • 很明显,他们希望人们停止在return 表达式中随意加上括号。

标签: c++ c++11 c++14 decltype type-deduction


【解决方案1】:

他们想要一种获取标识符声明类型的方法。

他们还想要一种获取表达式类型的方法,包括有关它是否是临时的信息。

decltype(x) 给出标识符x 的声明类型。如果您传递decltype 不是标识符的东西,它会确定类型,然后为左值附加&,为xvalues 附加&&,为prvalues 不附加任何内容。

从概念上讲,您可以将其视为变量类型和表达式类型之间的差异。但这并不是标准的描述方式。

他们可以使用两个不同的关键字来表示这两件事。他们没有。

【讨论】:

  • 但是当我在这两种情况下给出不是decltype(x + 1)decltype((x + 1)) 之类的标识符时,推断的类型是int,但不是int&,也不是更合乎逻辑的int&&(经过测试GCC 6.2boost::type_index 库)。为什么?
  • @bobeff 因为x+1 是prvalue?
  • @bobeff 请注意,decltype(x + 1) 将始终与decltype((x + 1)) 相同,无论x 的类型是什么,以及operator+ 可能如何被重载。原因是x+1 是一个表达式,因此在它周围添加括号不会改变任何内容。
  • @Columbo。也许是吧。来自hereprvalue 不能是多态的:它所标识的对象的动态类型始终是表达式的类型。
  • decltype 不一定给你一个对象的动态类型,即使你说decltype(x)x 引用的 object 的实际类型(当 xfoo.bar 时)可能在编译时未知。在这种情况下,decltype 应该产生x 引用的成员的声明类型(换句话说,当我们在实体类型“类成员”和“对象”之间进行选择时,我们必须选择“班级成员”)。这在规范中有点模棱两可,消歧依赖于语言和常识的先验知识/专业知识。
【解决方案2】:

需要区分实体和表达式。

考虑以下问题:

密西西比州有多长?

这个问题有两个答案:

  1. 密西西比州长 2,320 英里。
  2. 密西西比州有 11 个字母。

同样,当您询问x 的类型,而x 是一个标识符时,不清楚您是否指的是用于声明该标识符的类型(即与名称x 关联的类型) ),或由唯一提及该标识符组成的表达式的类型。事实上,可能有两个不同的关键字(例如entity_typeexpr_type)而不是一个重载的decltype。出于某种原因,委员会选择为这两种不同的用途重载decltype

【讨论】:

    【解决方案3】:

    来自decltype 提案的作者之一,J. Jarvi:

    已经有一段时间了,但这是我(想我)记得的:

    两个单独的关键字用于区分这两种语义 从未考虑过。 (引入新关键字可不是轻而易举的)。

    关于decltype((x))的语义变化,在讨论 核心工作组一致将(x) 视为一种表达方式,而不是 而不是标识符,这可能更“内部一致” 符合语言规则。

    人们意识到这可能会在某些情况下造成混淆 案例,但共识(虽然可能不是每个人的偏好)是 最终与标准的先前定义一致 什么是标识符,什么是表达式。

    您链接到 [this question's example] 的示例确实令人惊讶。当时,推导出一个 使用 decltype(auto) 的函数返回表达式的返回类型 还不是语言的一部分,所以我不认为这种特殊用途 任何人都在关注此案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-09
      • 2012-05-18
      • 1970-01-01
      • 2019-04-01
      • 2015-04-25
      • 2016-05-31
      相关资源
      最近更新 更多