【问题标题】:Is there any difference between `List x;` and `List x()``List x;` 和 `List x()` 之间有什么区别吗
【发布时间】:2012-09-06 09:30:39
【问题描述】:

标题来自著名网站C++ FAQ by Marshall Cline。

作者声称以下两个代码示例之间存在差异。

假设 List 是某个类的名称。然后函数 f() 声明了一个名为 x 的本地 List 对象:

void f()
{
    List x;     // Local object named x (of class List)
    ...
}

但是函数 g() 声明了一个名为 x() 的函数,它返回一个 List:

void g()
{
    List x();   // Function named x (that returns a List)
    ...
}

但是使用第二种变体真的错了吗?

如果它真的是一个声明,编译器不会抱怨你不能在一个函数中声明一个函数吗?

【问题讨论】:

  • 在其他函数内部声明(不定义)函数的“能力”源于C,如果您可能曾经想要这样做。在 C++ 中,它只会为您提供最麻烦的解析。 :s
  • clang++ 确实会产生警告:空括号被解释为函数声明 [-Wvexing-parse]
  • Visual Studio 类似: - 警告 C4930: 'blah blah(void)': 未调用原型函数(是否打算定义变量?)。

标签: c++ variable-declaration most-vexing-parse


【解决方案1】:

如果它真的是一个声明,编译器不会抱怨你不能在一个函数中声明一个函数。

当然不是。因为你可以用函数声明函数。

这被称为最令人头疼的解析,并且有据可查。其实代表编译器去处理就是报错了

List x();

作为变量声明。

但是使用第二种变体真的错了吗?

如果你想要一个变量,那么是的。如果你想声明一个函数......有点是的。可以,但通常你会在函数范围之外进行。

【讨论】:

  • 这并不是最麻烦的解析(只是其中的“一半”),最麻烦的解析是List x(List());
  • 但是由于List x(1); 是一个正确的陈述,人们会认为使用零参数构造函数创建对象的相应方法是List x();
  • @Kenny:那么,这是第二个最令人烦恼的解析。或者是第三个最烦人的解析,而你的解析是第二个,因为vector<string> v(istream_reader<string>(cin), istream_reader<string>()); 真的 非常烦人 ;-)
  • @Luchian:List x{}; 在 C++11 中工作吗?我不记得新奇的语法了。如果是这样,那值得一提。
  • @maba: 但是一个 C 函数执行 int some_function_name(); 在另一个函数中声明一个函数,不会编译为 C++。因为它将改为定义一个名为some_function_nameint,初始值为0。但你是对的,现在是2012 年,我们可以说如果C++ 不关心C 兼容性会更好。太晚了:-(
猜你喜欢
  • 2011-01-14
  • 1970-01-01
  • 2017-12-23
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-15
相关资源
最近更新 更多