Aggregate initialization with curly braces

2019-08-11 06:18发布

In C++11, are the aggregates allowed to be copied with curly-braces syntax? I have the following code:

struct s
{
    int x;
};
template<class T>
struct holder
{
    template<class A>
    holder(A&& x) : t{x} {}
    T t;
};

Each one of the statements below works.

auto s1 = s{1};
auto s2(s1);
auto s3{s1}; ///NOTE : this works!

However, the second statement below raises the error cannot convert 's' to 'int' in initialization.

holder<s> h{5};
holder<s> h1{s{5}};

I am using gcc 4.8.2. Why do I get this error?

2条回答
地球回转人心会变
2楼-- · 2019-08-11 06:53

First of all this code

struct s
{
    int x;
};
template<class T>
struct holder
{
    template<class A>
    holder(A&& x) : t{x} {}
    T t;
};

int main() 
{
    holder<s> h{5};
    return 0;
}

is compiled successfuly.

The invalid statement is

holder<s> h1{s{5}};

The problem is that in fact you are trying to execute

s s1 = { s{5} };

However the compiler is unable to convert an object of type s to an object of type int (that to initialize s1.x) when it tries to make assignment

s.x = s{5};
查看更多
Explosion°爆炸
3楼-- · 2019-08-11 06:57

In C++11, when a type T is an aggregate type, initialisation using { ... } performs aggregate initialisation. Aggregate initialisation always initialises the members of T, not T itself.

Although this is exactly what the standard requires, this is unwanted, which is why in a future standard, the rule will likely be changed to make a special exception for initialisation from the same type. This is core language issue 1467.

Until that time, unfortunately, the error you are getting is entirely correct, and you will have to work around it.

查看更多
登录 后发表回答