Oersted
Oersted

Reputation: 2536

Why is the explicitly defaulted default constructor implicitly deleted when there is a const std::vector data member?

I've got a code really similar to the snippet below:

#include <vector>

struct dummy
{
    std::vector<int> const data;
    dummy() = default;
};

Most compilers accept this code without a glitch except clang for versions 9 to 14 that says:

warning: explicitly defaulted default constructor is implicitly deleted [-Wdefaulted-function-deleted]
note: default constructor of 'dummy' is implicitly deleted because field 'data' of const-qualified type 'const std::vector' would not be initialized

In clang 15 the issue disappears again. Live

NB if const is removed, the error disappears also.

Yet I would have expect data to be initialized to a const empty vector.

Is this a clang bug? Otherwise, why is this code rejected (and why other compilers do not complain)?

Upvotes: 3

Views: 1243

Answers (1)

user17732522
user17732522

Reputation: 76688

Before resolution of CWG 2394 a defaulted default constructor was defined as deleted, if any const non-static member of class type without a default initializer did not have a user-provided default constructor.

The intention of this rule is to avoid the situation that you default-initialize the object to an indeterminate state that then can't possibly be modified to any usable state, which can only be wrong.

However, the condition isn't quite achieving that and the DR resolves it by making the same requirement as of const variable declarations instead, which, after resolution of NB comment RU1 in P0490, correctly consider that even a non-user-provided default constructor may correctly initialize.

Now the issue is that libstdc++ implements the default constructor of std::vector by defaulting it (see e.g. github mirror). The result is that the default constructor is not user-provided.

This seems to be a valid implementation, even before the CWG issue or NB comment resolution, because the container requirements are stated only in expressions and declarations that need to be well-formed and it doesn't seem to include any const default initialization as far as I can tell.

So it will fail in Clang versions which don't yet implement the defect report and when using libstdc++.

I haven't checked, but the older versions of Clang are probably using older libstdc++ versions where the default constructor is not yet implemented this way. (see GCC commit e6cad9872b098f50aefb39019b6b1ba74d8c6c07 from 2018)

Upvotes: 6

Related Questions