Does binding temporary to a reference require a copy constructor in C++?

寵の児 提交于 2020-01-03 08:38:29

问题


Consider the following code:

class A {
  A(const A&);
 public:
  A() {}
};

int main() {
  const A &a = A();
}

This code compiles fine with GCC 4.7.2, but fails to compile with Visual C++ 2010 with the following error:

test.cc(8) : error C2248: 'A::A' : cannot access private member declared in class 'A'
        test.cc(2) : see declaration of 'A::A'
        test.cc(1) : see declaration of 'A'

So is it necessary to have a copy constructor accessible when binding a temporary to a reference?

This is somewhat related to my previous question:

Is there a way to disable binding a temporary to a const reference?


回答1:


So is it necessary to have a copy constructor accessible when binding a temporary to a reference?

Post C++11 - No
Pre C++11 - Yes.


This code compiles fine with GCC 4.7.2 because it is compliant with the C++11 standard.

C++11 standard mandates that when a const reference is initialized from prvalue, it must be bound directly to the reference object and no temporary is permitted to be created. Also, the copy constructor is not used or required.

Prior to C++11 the rules were different. And this behavior(whether copy constructor will be called) is implementation defined. C++03 allowed the copy constructor being called while binding a const reference to an temporary and hence post C++11 the copy constructor needs to be accessible. Visual C++2010 adheres to the C++03 standard.




回答2:


Section 8.5.3.5 of the C++03 standard states that this is implementation-defined:

If the initializer expression is an rvalue, with T2 a class type, and "cv1 T1" is reference-compatible with "cv2 T2," the reference is bound in one of the following ways (the choice is implementation-defined):

-- The reference is bound to the object represented by the rvalue (see 3.10) or to a sub-object within that object.

-- A temporary of type "cv1 T2" [sic] is created, and a constructor is called to copy the entire rvalue object into the temporary. The reference is bound to the temporary or to a sub-object within the temporary.

The constructor that would be used to make the copy shall be callable whether or not the copy is actually done.

So it appears that both implementations are consistent with the C++03 standard.

The last sentence is a little confusing, but the way I read it, it means that the implementation may choose the second way, but still optimize away the copy. In that case, the copy constructor would have to be accessible even though the copy wasn't actually done, similar to return value optimization.

With the C++11 standard, the second way is no longer an option.




回答3:


Visual C++ is incorrect; the Standard does not indicate that the copy constructor must be accessible to bind a const reference to a temporary.



来源:https://stackoverflow.com/questions/13898750/does-binding-temporary-to-a-reference-require-a-copy-constructor-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!