【问题标题】:Meaning of I(I())I(I()) 的含义
【发布时间】:2018-01-11 18:42:45
【问题描述】:

示例代码:

typedef int I;
struct X{ X(int); };

int main()
{
    int(int());
    X(X());
    I(I());
}

int(int()); 行是一个使用函数转换符号的表达式——它是一个临时的int,用值初始化的int 初始化。

X(X()); 行是一个名为X 的函数的声明,它不带任何参数返回结构X

我的问题是:I(I()) 这里是什么意思?标准中的哪些规则决定了这三种情况的含义差异?

【问题讨论】:

  • typedef int I 使I 的行为完全类似于int。它只是分配另一个名称。因此I(I())int(int()) 具有完全相同的含义。有关typedef 的更多信息,请参阅[dcl.typedef]。
  • 根据gcc/clang,对于X,函数声明I返回int
  • 这三个都是函数声明
  • @Sopel:错误。正如问题中明确指出的那样,第一个不是函数声明。 int 是关键字这一事实在第一种情况下产生了重大影响。
  • 哎呀,对不起,没有名字,你是对的

标签: c++ language-lawyer most-vexing-parse


【解决方案1】:

规则说,如果一个构造对于声明或语句的语法有歧义,那么它被认为是一个声明。

[stmt.ambig] 1 在涉及表达式语句和声明的语法中存在歧义:表达式- 以函数式显式类型转换 (5.2.3) 作为其最左边的子表达式的语句可以是 indis- 可以从第一个声明符以 ( 开头的声明中区分出来。在这些情况下,声明是 声明。

X(X()); 是模棱两可的,因为它可能是一个强制转换,也可能是一个函数声明,所以它被认为是一个声明。

int(int()); 不能是函数声明,因为作为关键字的 int 不是函数的有效名称。所以,没有歧义,这是一个演员表。

同样,I(I()); 不能是函数声明,因为尽管不是关键字,I 也不是有效名称,因为它会将类型 I 重新声明为函数,这是不允许的,所以它是演员表。

【讨论】:

  • 你说I(I());是什么意思?
  • @M.M 据我了解规则,它是一个函数转换,并且值是临时初始化的,int(int()) 也是如此。
  • 可能是不允许重新定义 typedef 的规则:A name declared with the typedef specifier becomes a typedef-name. Within the scope of its declaration,typedef-name is syntactically equivalent to a keyword and ...。关键字可能不会被重新定义……但这似乎有点模糊。
  • 规则是这样的:eel.is/c++draft/basic.scope.declarative#4 仅当 typedef 与另一个声明位于同一声明区域时才适用。如果其中一个在嵌套范围内,则不会。这条规则的目的是尽可能地禁止这种愚蠢的行为,只保留与 C 的兼容性(例如,它同时具有一个名为 stat 的函数和结构)
猜你喜欢
  • 1970-01-01
  • 2017-01-12
  • 2014-03-27
  • 2020-08-15
  • 2017-02-15
  • 1970-01-01
  • 1970-01-01
  • 2019-02-12
相关资源
最近更新 更多