В инициализации класса и списке инициализаторов

Недавно я обнаружил, что вы не можете иметь одновременно инициализацию классов и список инициализаторов.
Сбой следующего кода:

struct s
{
int i=0;
};
int main() {
s s1; //s1.i = 0
//s s2={42}; //fails
return 0;
}

Если я удаляю инициализацию класса in, список инициализаторов работает нормально!

Может кто-нибудь объяснить мне, почему такая вещь не допускается?

4

Решение

На самом деле это разрешено в C ++ 14.

struct s
{
int i=0;
};

int main() {
s s1;
s s2 = {42}; // succeeds
}

Вероятно, ваш компилятор просто не реализует новое правило в C ++ 14. Однако последняя версия clang принимает это и делает все правильно в режиме C ++ 14.

Когда в C ++ 11 была добавлена ​​инициализация в классе, она была указана так, что она не позволяла классу быть агрегатом. Это было сделано потому, что в то время концепция агрегирования была тесно связана с типами PoD, которые должны быть легко конструируемыми. Наличие инициализации в классе означает, что тип больше не является тривиально конструируемым. Однако с тех пор эти две концепции стали более независимыми, и поэтому для C ++ 14 было принято короткое предложение, отменяющее это решение.

7

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

Эта инициализация:

s s1 = { 42 };

требует, чтобы s быть совокупный, или что у него есть действительный конструктор, например, int или std::initializer_list,

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

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

struct s
{
s(int i) : i(i) {}
int i=0;
};

Я считаю, что это ограничение было смягчено для C ++ 14.

Увидеть Что такое агрегаты … для дополнительной информации.

4

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