为什么这个代码可以消除副本

Why can this code elide a copy?

本文关键字:副本 代码 为什么      更新时间:2023-10-16

可能的重复:
构造函数调用机制
为什么使用一组空的括号来调用没有参数的构造函数是错误的?

为什么这个代码可以消除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下也不输出任何内容。

问题不是复制省略,而是声明的含义:

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

对编译器来说是一个函数声明。谷歌/搜索SO最令人烦恼的解析。C++常见问题小册子中的更多内容,包括解决方法。


[1]:这与完全不同,因为这需要从AB隐式转换。如果B定义为:

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

那么这将不是一个替代方案。

B b(A());

你认为这声明了一个变量吗?编号

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

请参阅本主题:

  • 最令人烦恼的解析:为什么不;t A A((((;工作

因此,如果您想声明一个变量,请在A()周围加一个大括号作为:

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

使用:

B b((A()));

您的行是一个函数声明。不幸的是,C允许函数内部的函数声明(BTW对我来说似乎很无用(,所以出于向后兼容性的原因,C++允许这样做。你可以用额外的括号强制变量定义。