C ++ 11 в gcc 4.8.1: инициализация списка для конструктора копирования не работает

Я поощряю с этой проблемой:
Если у меня есть

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

GCC дает:

move.cc: В функции int main ():
move.cc:15:7: ошибка: слишком много инициализаторов для «A»
A b {a};

Но когда я использую A b (a) вместо A b {a}, все компилируется правильно. И если я объявляю конструктор по умолчанию, он тоже компилируется. Почему так работает?

9

Решение

Класс является агрегатом, поэтому инициализация списка будет выполнять агрегатную инициализацию и не будет учитывать неявно объявленные конструкторы.

Так как нет элементов данных, только пустой список может быть допустимым агрегатным инициализатором.

Но когда я использую A b(a) вместо A b{a} все компилируется правильно.

При прямой инициализации будет использоваться неявный конструктор, а не попытка агрегированной инициализации.

И если я объявляю конструктор по умолчанию, он тоже компилируется.

Объявляя конструктор, класс больше не является агрегатом, и его можно инициализировать только с помощью конструктора.

14

Другие решения

Когда не определяешь свой конструкторы class A будет считаться совокупный (То есть. набившие оскомину-данные) тип хранения.

Имея дело с совокупностью, Список инициализация не будет рассматривать неявно объявленные конструкторы, вместо этого он попытается инициализировать члены вашего объекта напрямую.

В случае A b { a } где A это агрегат, который компилятор попытается инициализировать первым A со значением a; это, конечно, потерпит неудачу, так как A не содержит участников.


Что говорит стандарт?

[8.5.1 Aggregates]

1) Агрегат — это массив или класс (раздел 9) без предоставления пользователем
конструкторы (12.1)
, нет скобки или равных инициализаторов для нестатических
элементы данных (9.2), нет частных или защищенных нестатических элементов данных
(Раздел 11), без базовых классов (раздел 10) и без виртуальных функций
(10.3).

2) Когда агрегат инициализируется списком инициализаторов, как
указанные в 8.5.4, элементы инициализатора принимаются как
инициализаторы для членов агрегата
, в возрастающем индексе
или заказ участника. Каждый член инициализируется копией из
соответствующее предложение-инициализатор. Если предложение инициализатора является
Выражение и сужающее преобразование (8.5.4) требуется для преобразования
выражение, программа плохо сформирована.

9

GCC следовал стандарту, но это был известный дефект, см. основной вопрос 1467. Отчет о дефектах был исправлен в ноябре 2014 года, и новое поведение поддерживается в следующем основном выпуске GCC (версия 5.1, выпущенная в апреле 2015 года).

2
По вопросам рекламы [email protected]