2

I have the following code :

#include <iostream>
#include <optional>

class Test
{
    public:
    Test() = delete;
    Test& operator=(const Test&) = delete;
    Test& operator=(Test&&) = delete;
    Test(const Test&) = delete;
    Test(Test&&) = delete;
};

int main()
{
    Test test{};
}

This code mostly is compiled with various compilers (gcc and clang) and the program is terminated successfully. My question here is how the object Test is constructed. which constructor is called? Here https://www.onlinegdb.com/online_c++_compiler With C++20 selected as the std the compilation fails but with 17 the code compiles.

Jan Schultke
  • 17,446
  • 6
  • 47
  • 96

1 Answers1

4

You are using a direct list initialization to initialize test here. Which in turn, given the nature of your object, does an aggregate initialization. The aggregate initialization does nothing, since the initializer list is empty.

So no constructor is called for test.

EDIT from the comments

Since C++20, if a class has a deleted constructor it is no longer an aggregate because the constructor is user-declared, while in C++17 the constructor needed to be user-provided to prevent the class to be considered an aggregate. This is why the code is valid in C++17 but ill-formed in C++20.

Dorian
  • 490
  • 2
  • 10
  • `Test` is not an aggregate, so aggregate initialization does not apply here. – NathanOliver Jul 13 '23 at 14:09
  • 2
    And as of C++20, this type is no longer considered an aggregate. (In C++17, this is an aggregate because the members are not user-defined. In C++20, "user-declared" is enough to prevent this from being an aggregate) – Drew Dormann Jul 13 '23 at 14:09