PYA
PYA

Reputation: 8636

Why deleting copy constructor for member variable doesnt prevent defaulting copy constructor

class A {
public:
    A() = default;
    A(const A&) = delete;
    A(A&&) = delete;
};

class B {
public:
    B() = default;
    B(const B&) = default;
    B(B&&) = default;

    A a_;
};

int main() {
    B b{};
    static_cast<void>(b);
}

Why does this compile? the copy constructor should not have a default definition, since A has a deleted copy constructor. What does a default copy constructor mean in such a case? What am I missing here?

Upvotes: 0

Views: 99

Answers (2)

Kerrek SB
Kerrek SB

Reputation: 476990

Declaring a special member as defaulted does not mean that there will be a usable definition. Rather, = default means "fill in the plausible meaning here", and that can also mean that the member ends up being defined as deleted, if that's the only plausible thing (e.g. if class members aren't copyable).

The precise rules are in [class.copy.ctor]:

[...] A defaulted copy/move constructor for a class X is defined as deleted (9.4.3) if X has:

  • a potentially constructed subobject type M (or array thereof) that cannot be copied/moved because overload resolution (11.3), as applied to find M’s corresponding constructor, results in an ambiguity or a function that is deleted or inaccessible from the defaulted constructor,
  • [...]

That is, your B::B(const B&) ends up being defined as deleted. You will notice this as soon as you're trying to make a copy of b.

Upvotes: 2

cplusplusrat
cplusplusrat

Reputation: 1445

The default here translates to delete I think. Someone needs to lookup the standards document to confirm it. But if you added a line in your main() which was B foo = b;, you will start getting compiler errors I am sure. You won't be able to copy B in spite of the default keyword used for copy ctor.

EDIT: Here is the error I got when I tried copying B.

‘B::B(const B&)’ is implicitly deleted because the default definition would be ill-formed

Upvotes: 1

Related Questions