user11923373
user11923373

Reputation: 471

Use of `= default` allowing private constructor to be accessed

I have the code:

class Key
{
private:
    // If I use the = default keyword here, the line "Key a = {};" compiles
    // If I instead use Key() {}, that same line does not compile (as the constructor is private)
    Key() = default;

    Key(Key const &) = default;
    Key(Key &&) = default;

    Key & operator=(Key const &) = default;
    Key & operator=(Key &&) = default;
};

int main()
{
    // This line compiles when = default is used, but not when an empty constructor is used
    Key a = {};
    return 0;
}

What, specifically, is the difference between the default constructor and the empty constructor in this specific instance? Also, I would like for this to NOT compile, is explicitly writing my own empty constructor the only way to do so here? Note: This was tested with both GCC 8.3 and Clang 10.0 with identical results.

Upvotes: 7

Views: 94

Answers (1)

SergeyA
SergeyA

Reputation: 62563

When default constructor is defaulted, pre C++20, this code compiles, as your class with defaulted constructor is an aggregate, and you can initialize aggregates through aggregate initialization

Key a = {}; // interpreted as aggregate initialization and bypasses access qualifier on constructor

This code would not compile in C++20 or above, as defaulted constructor makes it non-aggregate:

Key a = {}; // interpreted as calling a constructor, since Key is no longer an aggregate.

In this case compiler tries to actually call the constructor, and can't, since constructor is private.

When you have

Key() { };

Your class is no longer an aggregate in any C++ dialect, since it has a user-defined, non-defaulted constructor.

Upvotes: 7

Related Questions