【问题标题】:c++11 decltype(e) is the type of the entity named by ec++11 decltype(e)是e命名的实体的类型
【发布时间】:2018-02-11 17:20:57
【问题描述】:


我不是在问decltype((x)),我知道它是如何工作的。

根据 N4687 草案第 10.1.7.2 节

    4 For an expression e, the type denoted by decltype(e) is defined as follows:
        ...
(4.2)   — otherwise, if e is an unparenthesized id-expression or an unparenthesized class
          member access (8.2.5), decltype(e) is the type of the entity named by e. If
          there is no such entity, or if e names a set of overloaded functions, the
          program is ill-formed;
        ...

还有例子

struct A { double x; };
const A* a = new A();
decltype(a->x) x3; // type is double

我的问题是,
a->xconst double,但为什么 x3 是 doubleconst 去哪儿了?
顺便说一句,decltype(e) is the type of the entity named by e 到底是什么意思?

【问题讨论】:

  • a->x 是 const double 吗?您刚刚将其声明为 double x 而不是 const double
  • 我知道x 被声明为双精度。但是a->xeeconst double,所以xconst double,不是吗?
  • 提交错误报告
  • 我不认为const 对象的成员本身就是const,除非在类定义中声明const。只是禁止修改它们。
  • @user2357112 - 它们是常量。限定符递归地应用于聚合的成员。这种情况只是简单地指定为其他行为(尽管不是很清楚)。

标签: c++ c++11 language-lawyer decltype


【解决方案1】:

类成员访问表达式命名的“实体”是该类成员,在本例中为A::x

A::x 的类型是double

【讨论】:

  • 您可能要补充一点,这与A::x 相同因为同一段提到并适用于 id 表达式。
  • 你能帮帮我吗?你在哪里找到entity named的定义?
  • @Caesar - 按照标​​准,这是糟糕的措辞。 “id-expression”(如段落中所述)类似于A::x。您当然同意应该解析为double。好吧,你引用的那个子弹几乎说A::xa->x 解决相同的问题。
【解决方案2】:

这个领域的标准似乎模棱两可。

实体是值、对象、引用、函数、枚举器、类型、类成员、位域、模板、模板特化、命名空间或参数包。

表达式a->x 可以说是struct A 的一个成员 x,其类型为double。同样的表达式也可以说是命名一个类型为const doubleobject。这两件事都是实体。规范性文本并没有明确说明预期的解释是第一个,只能从示例中推断出来。

【讨论】:

  • 实体定义出现在哪里?哦,无论如何 +1。
  • @StoryTeller [basic]/3(可以在索引中找到指针)。
  • 据说 CWG 引入“entity”的唯一原因是因为“thingy”被认为不适合 ISO 标准。
  • @T.C.他们还删除了原子衰变脚注。永远不要原谅,永远不要忘记。
  • 这里有一个微妙的区别。成员子对象的 type 不受其完整对象的 cv 限定影响。当然,很难证明是否定的,但可以从 [basic.type.qualifier]/1 中“const object”的定义推断为“const T 类型的对象或此类对象的非可变子对象”(同样对于volatile)。如果完整对象上的 cv 限定影响其子对象的类型,则定义的第二部分将是完全多余的。
【解决方案3】:

N4687 [dcl.type.simple] ¶4.2 ...如果e 是未加括号的id-expression 或未加括号的类成员访问,decltype(e) 是命名实体的类型e.

根据 [expr.ref],类成员访问权限是 .->

[basic] ¶3 entity 是值、对象、引用、函数、枚举器、类型、类成员、位域、模板、模板特化、命名空间或参数包。

¶4 nameidentifieroperator-function-idliteral-operator-id、conversionfunction-idtemplate-id,表示实体或标签。

¶5 每个表示实体的名称都由声明引入。

这里有一个歧义:a->x 既是类成员又是对象(成员子对象)。需要注意的重要一点是decltype(e)命名为 e 的实体的类型。唯一可以命名的实体是那些由声明引入的实体(¶5)。在这个意义上,成员子对象没有名称,因为它没有被声明。剩下的唯一选择是 decltype(x->a) 必须是类成员的类型(而不是对象成员)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-16
    • 2015-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多