为什么复制构造函数在通过const引用传递临时时被调用?

dav*_*vka 23 c++ gcc pass-by-reference copy-constructor

我将一个未命名的临时对象传递给使用const ref参数定义的函数.该类的副本是私有的,我收到编译错误.我不明白为什么在这种情况下调用复制构造函数.

class A {
public:
  A(int i) {}
private:
  A(const A&) {}
};

void f(const A& a)
{
}

int main()
{
  f(A(1)); // <-- error here: 'A::A(const A&)' is private
}
Run Code Online (Sandbox Code Playgroud)

正如所料,当我将主要更改为:

A a(1);
f(a);
Run Code Online (Sandbox Code Playgroud)

有用.

编辑:编译器是gcc 4.1.2

CB *_*ley 20

表达式A(1)rvalue 5.2.3 [expr.type.conv].

在使用const作为rvalue的表达式初始化引用(函数参数)时,编译器可以创建临时表并将该表达式的值复制到临时表并将该表达式绑定到该临时表.8.5.3 [dcl.init.ref]/5.

[...]无论副本是否实际完成,用于制作副本的构造函数都应该是可调用的.

请注意,此行为是由于下一版本的C++中的更改.在新标准中,const从类prvalue初始化的引用必须直接绑定到引用对象; 在这种情况下,不允许创建临时文件,并且不使用或不需要复制构造函数.


eta*_*ion 18

您可以在需要复制构造函数的临时对象中找到问题的答案,或直接转到http://gcc.gnu.org/bugs/#cxx%5Frvalbind

C++标准说在这个上下文中应该创建一个临时对象,其内容用我们试图绑定到引用的对象的副本填充; 它还说可以省略临时副本,但仍然需要检查复制构造函数的语义约束(例如可访问性).

有关详细信息,请参阅以下C++标准段落:[dcl.init.ref]/5,bullet 2,sub-bullet 1和[class.temporary]/2.

从GCC 4.3.0开始,GCC不再为此情况提供错误.此更改基于C++语言委员会的意图.截至2010-05-28,C++ 0x标准的最终提议草案允许此代码无错误.