为什么这段代码可以删除副本?

时间:2011-07-14 08:09:22

标签: c++ most-vexing-parse

  

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

为什么code可以删除A的所有副本?

#include <iostream>

class A
{
public:
  A() {}
  A(const A&) { std::cout << "Copy" << std::endl; }
};

class B
{
public:
  B(const A& a_) : a(a_) {}
private:
  A a;
};

int main()
{
  B b(A());
}

此代码显然没有A的副本,并且在ideone下的gcc 3.4下没有输出任何内容。

3 个答案:

答案 0 :(得分:9)

问题不是复制省略,而是宣言的含义:

B b(A());
// To get it working the way you expect [1]
B b = B(A());
// Or the slightly more obtuse.
B b((A()));

编译器是一个函数声明。 Google /搜索SO以获取最令人烦恼的解析。 C++ FAQ lite中的更多内容包括解决方法。


[1] :这不是完全相同,因为这需要从A到{{隐式转换1}}。如果B定义为:

B

然后这不是另类选择。

答案 1 :(得分:7)

B b(A());

你认为这声明了一个变量?否。

它声明了一个函数b,其返回类型为B并接受A (*)()类型的参数。

请参阅此主题:


因此,如果您想声明一个变量,请在A()附近添加一个大括号:

B b((A())); //it declares an object

答案 2 :(得分:1)

使用:

B b((A()));

你的行是一个函数声明。不幸的是C允许函数内部的函数声明(BTW对我来说似乎没用),因此为了向后兼容性,C ++允许这样做。您可以使用额外的括号强制执行变量定义。