Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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};
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top