初始化结构成员时可能出现的MSVC 2013错误 [英] Possible MSVC 2013 bug when initializing struct members

查看:66
本文介绍了初始化结构成员时可能出现的MSVC 2013错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

MSVC 2013抱怨以下代码,尽管它在g ++中可以正常工作。

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;
}

请注意,更改 struct

Note that changing the struct as follows resolves the issue.

struct A
{
    double x, y;
};

错误消息是:


错误1错误C2440:'initializing':无法从
'initializer-list'转换为'A'

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


推荐答案

实际上,Visual Studio是正确的。

您的课程不是集合,因此可能无法在其上使用聚合初始化:

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


[C ++ 11:8.5.1 / 1] :集合是一个数组或一个类(第9条),没有用户提供的构造函数(12.1),没有用于非静态数据的
brace-or-equal-initializers 成员(9.2),没有私有或受保护的非静态数据成员(条款11),没有基类(条款10)以及没有虚拟函数(10.3)。

[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]:初始化形式为

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

以及 new 表达式(5.3 .4), static_cast 表达式(5.2.9),功能符号类型转换(5.2.3)以及基本和成员初始值设定项(12.6.2)被称为直接初始化

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]:初始化程序的语义如下。 目标类型是要初始化的对象或引用的类型,源类型是初始化器表达式的类型。当初始化程序为 braced-init-list 或为括号括起来的表达式列表时,未定义源类型。

[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.


  • 如果初始化程序是 braced-init-list ,则对象是 list-initialized (8.5.4)。

  • [...]

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

我不会全部引用,但是 [C ++ 11:8.5.4 / 3] 是我们故事的结尾,其中定义了 list-initialization 。它表明,没有初始化程序列表构造函数,并且鉴于您的列表包含两个元素(不是一个也不是零),则您的程序格式不正确。

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实际上接受您的程序(感谢Igor,示例),尽管clang错误地做了( 示例,相同的信用)。

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


如果您是对的,那么这些对于简单结构来说是个可怕的消息,因为我倾向于在所有地方都使用默认初始化: struct A {double x {},y {}; };

是的,如果您希望C ++ 11类能够是集合体。 :)

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

C ++ 14实际上从 8.5.1 /中删除了
brace-or-equal-initializers 限制1
,因此切换到新标准将带您进入想要的位置。

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.

这篇关于初始化结构成员时可能出现的MSVC 2013错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆