【问题标题】:Why do I need double parentheses  in constructor calls like: foo x( (bar()) ); [duplicate]为什么在构造函数调用中需要双括号 ,例如: foo x( (bar()) ); [复制]
【发布时间】:2012-07-13 20:19:11
【问题描述】:

可能重复:
Why is it an error to use an empty set of brackets to call a constructor with no arguments?

我看过C++ FQAentries关于嵌套构造函数调用和支撑的内容,并且一直想知道 C++ 解析器如何解析两个以及为什么解析器无法解析它。

所以我明白为什么foo xxx(); 是模棱两可的。但是是什么让foo x(bar()); 模棱两可,因为它显然不是前向声明。 (即:应该有一个可以成功检测到这一点的语法)。

有人能解释一下 C++ 语法那部分的限制和歧义吗?

【问题讨论】:

  • google“最麻烦的解析”
  • 您链接的常见问题解答条目解释了这一点。倒数第三段。
  • 这些是大括号:{}。这些是括号:().

标签: c++ compiler-theory most-vexing-parse


【解决方案1】:
foo x(bar());

这可能是:

1) 一个名为x 的变量的声明,其值为默认构造的bar。这与foo x = bar(); 相同。

2) 一个名为x 的函数的声明,它返回foo 并接受一个参数——一个返回bar 并且不接受任何参数的函数。这个和foo x(bar (void));是一样的

【讨论】:

  • 我的意思是这里不是 2 无效声明吗?或者是什么意思?这是否意味着 bar 是一个函数原型,而 foo 将函数指针作为第一个参数?那不应该是 bar (*)() 吗?
  • 不,2 不是无效声明。 foo x(bar (void)) 表示x 是一个返回foo 并接受bar (*)(void) 的函数。 (*) 不必明确的原因是函数声明有一条规则,如果参数类型是函数类型,则参数被“调整”为指向该函数类型的指针。这与如果参数是数组,则将其“调整”为指针类型的规则完全相同; void a(int x[]) 完全等价于void a(int *x),foo x(bar()) 等价于foo x(bar(*)())。
【解决方案2】:

C++ FQA 是一堆垃圾。忽略它。

至于foo x(bar()),它和foo x()一样模棱两可,除了x的类型也带一个参数,它是一个函数。在此处添加一个指针,您就会明白我的意思了。

foo (*x)();
foo (*x)(bar(*)());

即使允许这样做的想法也很愚蠢,但现在没有人可以改变它。

(我偷偷怀疑这个语法有点不对劲,但我相信有人会纠正我)。

【讨论】:

  • 我不认为x这里是函数指针,只是使用时衰减为指针的函数声明。
  • 不是的,我只是添加了指针,让它更清楚它是如何等价的。
猜你喜欢
  • 2012-12-14
  • 1970-01-01
  • 2011-08-30
  • 2013-11-23
  • 2020-10-03
  • 2020-11-15
  • 1970-01-01
  • 2015-10-03
  • 2017-03-26
相关资源
最近更新 更多