Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ initialization strange behavior

typedef struct node {
    
    int val;
    int val2;
    
    node(int a, int b) : val(a), val2(b) {}
    node(int val) = delete;
}node;

int main()
{
    node a = {3};
    cout << a.val << " " << a.val2 << endl;
    return 0; 
}

The above code gives compile error showing that use of deleted function node::node(int).

However, when I remove node(int a, int b) : a(val), b(val2) {}, this code compiles without a problem. How would this happen?

like image 230
syacer Avatar asked Dec 17 '22 11:12

syacer


1 Answers

Before C++20 explicitly deleted constructors are allowed for aggregate type. If you remove node(int a, int b) and leave node(int val) = delete; only, node is considered as aggregate and node a = {3}; performs aggregate initialization, constructors won't be used, as the effect a.val is initialized as 3 and a.val2 is initialized as 0 directly.

no user-provided constructors (explicitly defaulted or deleted constructors are allowed) (since C++11) (until C++17)

no user-provided, inherited, or explicit constructors (explicitly defaulted or deleted constructors are allowed) (since C++17) (until C++20)

C++20 has fixed this behavior. node a = {3}; performs list initialization, the deleted constructor will be used and the code is ill-formed.

no user-declared or inherited constructors (since C++20)

BTW: The usage of typedef in the definition of node is superfluous, you can just write it as struct node { ... };.

like image 191
songyuanyao Avatar answered Dec 26 '22 11:12

songyuanyao