This code, with a const A& a member in B, where A has a deleted copy constructor, doesn't compile in GCC 4.8.1, but it works OK in clang 3.4:
class A {
public:
A() = default;
A(const A&) = delete;
A& operator=(const A&) = delete;
};
class B{
public:
B(const A& a)
: a{a}
{ }
private:
const A& a;
};
int main()
{
A a{};
B b{a};
}
Which one of the compilers is right?
The error in GCC is:
prog.cpp: In constructor ‘B::B(const A&)’:
prog.cpp:11:14: error: use of deleted function ‘A::A(const A&)’
: a{a}
^
prog.cpp:4:5: error: declared here
A(const A&) = delete;
^
Ideone: http://ideone.com/x1CVwx
Your example can be reduced to
class A {
public:
A() = default;
A(const A&) = delete;
A& operator=(const A&) = delete;
};
int main()
{
A a{};
A const& ar1(a);
A const& ar2{a}; // fails on gcc 4.8
}
The initialization of ar2 fails on gcc-4.8 with the error
error: use of deleted function ‘A::A(const A&)’
It compiles cleanly on clang3.4 and gcc4.9. This is the result of the resolution to CWG issue 1288.
N3337 contains the following language for list-initialization:
§8.5.4/3 [dcl.init.list]
List-initialization of an object or reference of type
Tis defined as follows:
—...
— Otherwise, ifTis a reference type, a prvalue temporary of the type referenced byTis list-initialized, and the reference is bound to that temporary
This, of course, means that the initialization of ar2 requires an accessible copy-constructor, hence the error.
The language has changed in N3797, where the initialization from an initializer list containing a single element takes precedence over the case quoted above.
— Otherwise, if the initializer list has a single element of type
Eand eitherTis not a reference type or its referenced type is reference-related toE, the object or reference is initialized from that element;...
— Otherwise, ifTis a reference type, a prvalue temporary of the type referenced byTis copy-list-initialized or direct-list-initialized, depending on the kind of initialization for the reference, and the reference is bound to that temporary.
So gcc 4.9 and clang 3.4 are implementing the resolution of issue 1288, while gcc 4.8 is following the wording in the C++11 standard.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With