Возможная ошибка MSVC 2013 при инициализации членов структуры

MSVC 2013 жалуется на следующий код, хотя он работает как положено в g ++. Похоже ли это на ошибку в 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 следующим образом решает проблему.

struct A
{
    double x, y;
};

Сообщение об ошибке:

Ошибка 1 ошибка C2440: «инициализация»: невозможно преобразовать из «списка инициализаторов» в «А»

 Lightness Races in Orbit27 сент. 2016 г., 17:46
@Liviu: я ответил.
 Lightness Races in Orbit27 сент. 2016 г., 17:42
@SamVarshavchik: Оказывается, у тебя плохой день волос;)
 Eissa N.28 июн. 2016 г., 03:52
@songyuanyao Я использую VS 2013 с обновлением 4 в версии Visual Studio Premium.
 Sam Varshavchik28 июн. 2016 г., 03:45
Я не вижу ничего плохого в этом коде. У MSVC просто плохой день волос.
 Destructor27 сент. 2016 г., 18:35
@LightnessRacesinOrbit: ваш ответ неверный. Лучше, если вы удалите этот неправильный ответ. Смотри мой ответ
 Liviu28 сент. 2016 г., 10:51
@Destructor Это не о C ++ 11 против C ++ 14, как о Visual Studio 2015 (2013 год должен быть еще хуже)
 Lightness Races in Orbit27 сент. 2016 г., 18:40
@ Деструктор: Ты прощен, ученик. На самом деле приятно обнаружить, что C ++ 14 изменил это, поэтому я добавлю это в качестве начальной загрузки.
 Lightness Races in Orbit27 сент. 2016 г., 18:36
@Destructor: Есть ли у вас критика кроме того, что ответ изменился в C ++ 14, который ОП не использует? Ваш ответ на самом деле согласен с моим в отношении C ++ 11, как этот вопрос помечен.
 Destructor27 сент. 2016 г., 18:38
@LightnessRacesinOrbit: ой очень жаль, что не заметил тег C ++ 11. Искренние извинения !!!
 1201ProgramAlarm28 июн. 2016 г., 03:29
На что жалуется компилятор (сообщение об ошибке)?
 songyuanyao28 июн. 2016 г., 03:48
Какую версию ты используешь?VS 2013 Кажется, начинается поддержка нестатических инициализаторов элементов данных из VS2013 RC.
 Liviu27 сент. 2016 г., 16:31
@ Игорь Почему бы вам не дать четкий ответ? Я искал его уже час ... Если вы правы, это ужасные новости для простых структур, потому что я склонен использовать инициализацию по умолчанию везде:struct A { double x{}, y{}; };
 Igor Tandetnik28 июн. 2016 г., 04:03
GCC не принимает это или; тольколязг делает, Я почти уверен, что Clang не прав, а два других правы: наличие инициализаторов членов вызываетA не быть агрегатом, и поэтому его нельзя инициализировать с помощьюагрегатная инициализация, Требуется двухпараметрический конструктор или конструктор, принимающийinitializer_list

Ответы на вопрос(1)

Решение Вопроса

На самом деле Visual Studio является правильным.

Ваш класс не является агрегатным, поэтому агрегатная инициализация не может использоваться для него:

[C++11: 8.5.1/1]: Агрегат - это массив или класс (раздел 9) без пользовательских конструкторов (12.1), нетскобки или равно-инициализаторы для нестатических элементов данных (9.2) нет личных или защищенных нестатических элементов данных (пункт 11), нет базовых классов (пункт 10) и нет виртуальных функций (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) называютсяпрямая инициализация.

[C++11: 8.5.1/16]: Семантика инициализаторов следующая.тип назначения тип инициализируемого объекта или ссылки иТип источника тип выражения инициализатора. Тип источника не определен, когда инициализатор являетсяприготовился-INIT-лист или когда это список выражений в скобках.

Если инициализатор являетсяприготовился-INIT-листобъектСписок инициализируется (8.5.4).[...]

И я не буду все это цитировать, но[C++11: 8.5.4/3], гдеСписок инициализация определяется, где наша история заканчивается. Это показывает, что без конструктора списка инициализаторов и учитывая, что в вашем списке есть два элемента (не один и не ноль), ваша программа плохо сформирована.

GCC на самом делене принять вашу программу (пример спасибо Игорю), хотя лязг ошибается (пример, тот же кредит).

Если вы правы, это ужасные новости для простых структур, потому что я склонен использовать инициализацию по умолчанию везде:struct A { double x{}, y{}; };

Да, пора прекратить это делать, если вы хотите, чтобы ваши классы C ++ 11 были агрегатными. :)

C ++ 14 фактически удалилскобки или равно-инициализаторы ограничение от8.5.1/1Таким образом, переход на новый стандарт поможет вам достичь желаемого.

 Liviu28 сент. 2016 г., 11:51
Спасибо, не первый раз, когда вы мне помогли, в третий раз я попытаюсь использовать эту систему PayPal
 Liviu28 сент. 2016 г., 11:47
извините, что потратил ваше время, но я не понимаю, как люди, которые используют Visual Studio (например, тег четко говорит), могут "переключиться на новый стандарт" (это все равно, что сказать: "переключиться на новый космический челнок" - о, нет ... тогда поезжайте в Россию!) и спасибо за загадочную таблицу (я полагаю, под вычетом вы говорите о "NSDMI для агрегатов")
 Mgetz28 сент. 2016 г., 16:57
В то время какОбновление 3 VS2015 добавило переключатели стандартной версии они в значительной степени влияют только на стандартную библиотеку AFAIK. Любое новое поведение должно появиться в vNext, как это обычно бывает в MSVC.
 Liviu14 окт. 2016 г., 10:03
Это будет сделано в следующей версии VS, AFAIUОсобенности C ++ 14/17 и исправления STL в VS «15» Preview 5
 Liviu28 сент. 2016 г., 10:50
Более новый стандарт? Я использую Visual Studio Professional 2015 с обновлением 3 (т. Е. C ++ 14): та же ошибка.
 Lightness Races in Orbit27 сент. 2016 г., 17:47
Настоящая проблема здесь - абсурдная сложность C ++, порождающая совершенно неизбежную путаницу.
 Lightness Races in Orbit28 сент. 2016 г., 11:36
@Liviu:Visual Studio на самом деле не отслеживает стандарты в унитарных порциях, Держу пари, что это изменение в C ++ 14, которого просто не последовало. Если вы запустите тестовый пример GCC с-std=c++14 Вы должны видеть, что это работает, все же.
 Lightness Races in Orbit28 сент. 2016 г., 11:48
@Liviu: я не обещаю, что они могут! Они должны обсудить это с Microsoft, а не со мной. Я только говорю вам, что определяет стандарт C ++, и что вам нужно использовать версию C ++ 14 этой «функции», чтобы избавиться от сообщения об ошибке. Как вы делаете это ваше личное дело! (Точно так же я не указываю на что-то конкретное в таблице; я просто доказываю, что VS 2015 не поддерживает весь C ++ 14; если вам нужны документы по конкретным функциям, вы можете найти их самостоятельно.) Важной частью этого ответа является то, что VS правильно относится к C ++ 11 (с которым вопрос также помечен).

Ваш ответ на вопрос