Possible MSVC 2013 bug when initializing struct members

大兔子大兔子 提交于 2019-12-09 12:57:46

问题


MSVC 2013 complains about the following code, while it works as expected in g++. Does this look like a bug in MSVC?

#include <iostream>
using namespace std;

struct A
{
    double x = 0.0, y = 0.0;
};

int main()
{
    A a{ 1.0, 2.0 };
    return 0;
}

Note that changing the struct as follows resolves the issue.

struct A
{
    double x, y;
};

The error message is:

Error 1 error C2440: 'initializing' : cannot convert from 'initializer-list' to 'A'


回答1:


Actually, Visual Studio is correct.

Your class is not an aggregate, so aggregate initialisation may not be used on it:

[C++11: 8.5.1/1]: An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no brace-or-equal-initializers 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).


[C++11: 8.5.1/15]: The initialization that occurs in the forms

T x(a);
T x{a};

as well as in new expressions (5.3.4), static_cast expressions (5.2.9), functional notation type conversions (5.2.3), and base and member initializers (12.6.2) is called direct-initialization.


[C++11: 8.5.1/16]: The semantics of initializers are as follows. The destination type is the type of the object or reference being initialized and the source type is the type of the initializer expression. The source type is not defined when the initializer is a braced-init-list or when it is a parenthesized list of expressions.

  • If the initializer is a braced-init-list, the object is list-initialized (8.5.4).
  • [...]

And I shan't quote it all, but [C++11: 8.5.4/3], where list-initialization is defined, is where our story ends. It shows that without an initializer-list constructor, and given that your list has two elements (not one and not zero), your program is ill-formed.

GCC actually doesn't accept your program (example thanks to Igor), though clang erroneously does (example, same credit).

If you are right, these are some terrible news for simple structures because I tend to use default initialization everywhere: struct A { double x{}, y{}; };

Yep, time to stop doing that, if you want your C++11 classes to be aggregates. :)

C++14 actually removed the brace-or-equal-initializers restriction from 8.5.1/1, so switching to a newer standard will get you where you want to be.



来源:https://stackoverflow.com/questions/38065676/possible-msvc-2013-bug-when-initializing-struct-members

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