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?
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.
Section 8.5.3.5 of the C++03 standard states that this is implementation-defined:
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.
Visual C++ is incorrect; the Standard does not indicate that the copy constructor must be accessible to bind a
const
reference to a temporary.