I have found that the possibility of usage of initializer list syntax for a class depends on whether or not the class fields have default values. Why?
To be precise, consider the following code:
class S
{
public:
int a;
};
...
int a;
S s{ a };
It compiles without any problems. But if I add a default value to the class field, it stops building:
class S
{
public:
int a = 0;
};
...
int a;
S s{ a };
Error 1 error C2440: 'initializing' : cannot convert from 'initializer-list' to 'S'
Why? What else influences such constructor generation?
In C++14, your code is valid and should compile with any C++14 compatible compiler.
In C++11 however:
If you do not have a default value for a
, your type is an aggregate, and thus aggregate initialization can be performed:
An aggregate is one of the following types:
array type
class type (typically, struct or union), that has
- no private or protected non-static data members
- no user-provided constructors , including those inherited from public bases (since C++17) (explicitly defaulted or deleted constructors are allowed) (since C++11)
- no virtual, private, or protected (since C++17) base classes
- no virtual member functions
- no default member initializers (since C++11, until C++14)
As soon as you add a default value for the attribute a
, your aggregate initialization cannot be performed anymore since your type stop being an aggregate.
The shown code compiles without any issues with gcc 6.1.1. You're likely using an older compiler that does not fully support C++14:
$ cat t.C
class S
{
public:
int a = 0;
};
void foo()
{
int a=4;
S s{a};
}
$ g++ -std=c++1z -g -c -o t.o t.C
$ g++ --version
g++ (GCC) 6.1.1 20160510 (Red Hat 6.1.1-2)
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With