Does link binding require reference to copy constructor in C ++?

Consider the following code:

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

This code compiles with GCC 4.7.2, but does not 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, do I need to have a copy constructor available when binding a temporary to a link?

This is somewhat related to my previous question:

Is there a way to disable the binding of a temporary link to const?

+7
source share
3 answers

. Do I need to have a copy constructor available when binding a temporary to a link?

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


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

The C ++ 11 standard indicates that when initializing a reference to a constant from prvalue it must be bound directly to the reference object, and time resolution is not allowed to be created. In addition, the copy constructor is not used or not required.

Before C ++ 11, the rules were different. And this behavior (the copy constructor will be called) is determined by the implementation. C ++ 03 allowed to call the copy constructor when binding the const link to a temporary one and, therefore, to the C ++ 11 message, the copy constructor should be available. Visual C ++ 2010 adheres to the C ++ 03 standard.

+4
source

Section 8.5.3.5 of the C ++ 03 standard states that this is determined by the implementation:

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

- The link is attached to the object represented by rvalue (see 3.10), or to a sub-object inside this object.

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

The constructor that will be used to create the copy must be called regardless of whether the copy is actually executed.

So, it looks like both implementations are compatible with the C ++ 03 standard.

The last sentence is a bit confusing, but the way I read it means that the implementation can choose the second way, but still optimize the copy. In this case, the copy constructor should be available, even if the copy did not actually run, similar to optimizing the return value.

In the C ++ 11 standard, the second method is no longer an option.

+2
source

Visual C ++ is incorrect; The standard does not indicate that a copy constructor should be available to bind a const reference to a temporary one.

0
source

All Articles