C++11 in gcc 4.8.1: list-initialization for copy constructor doesn't work

半城伤御伤魂 提交于 2019-11-29 18:37:18

问题


I encourages with this problem: If I have

class A
{
public:
};
int main()
{
   A a{};
   A b{a};
}

gcc gives:

moves.cc: In function ‘int main()’: moves.cc:15:7: error: too many initializers for ‘A’ A b{a};

But when I use A b(a) instead of A b{a} all compiles correctly. And if I declare default constructor it compiles too. Why does it work so?


回答1:


The class is an aggregate, so list-initialisation will perform aggregate initialisation, and won't consider the implicitly-declared constructors.

Since there are no data members, only an empty list can be a valid aggregate initialiser.

But when I use A b(a) instead of A b{a} all compiles correctly.

Direct initialisation will use the implicit constructor rather than attempting aggregate initialisation.

And if I declare default constructor it compiles too.

By declaring a constructor, the class is no longer an aggregate, and can only be initialised using a constructor.




回答2:


When not defining your own constructors class A will be considered an aggregate (ie. plain-old-data) storage type.

When dealing with an aggregate, list-initialization won't consider any implicitly declared constructors, instead it will try to initialize the members of your object directly.

In the case of A b { a } where A is an aggregate the compiler will try to initialize the first member in A with the value of a; this will of course fail since A doesn't contain any members.


What does the standard say?

[8.5.1 Aggregates]

1) An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no brace-or-equal-initializer s for non-static data members (9.2), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).

2) When an aggregate is initialized by an initializer list, as specified in 8.5.4, the elements of the initializer are taken as initializers for the members of the aggregate, in increasing subscript or member order. Each member is copy-initialized from the corresponding initializer-clause . If the initializer-clause is an expression and a narrowing conversion (8.5.4) is required to convert the expression, the program is ill-formed.




回答3:


GCC was following the standard, but that was a known defect, see core issue 1467. The defect report was resolved in November 2014 and the new behaviour is supported in the next major release of GCC (version 5.1, released April 2015).



来源:https://stackoverflow.com/questions/19112399/c11-in-gcc-4-8-1-list-initialization-for-copy-constructor-doesnt-work

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!