C ++ 11 позволяет в классе инициализировать нестатические и неконстантные члены. Что изменилось?
До C ++ 11 мы могли выполнять инициализацию в классе только для статических константных членов целочисленного типа или типа перечисления.Страуструп обсуждает это в своих C ++ FAQ, приведя следующий пример:
class Y {
const int c3 = 7; // error: not static
static int c4 = 7; // error: not const
static const float c5 = 7; // error: not integral
};
И следующие рассуждения:
Так почему же существуют эти неудобные ограничения? Класс обычно объявляется в файле заголовка, а файл заголовка обычно включается во многие единицы перевода. Однако, чтобы избежать сложных правил компоновщика, C ++ требует, чтобы у каждого объекта было уникальное определение. Это правило было бы нарушено, если бы C ++ допускал в своем классе определение сущностей, которые должны были храниться в памяти как объекты.
Однако C ++ 11 ослабляет эти ограничения, разрешая инициализацию в классе нестатических членов (§12.6.2 / 8):
В не делегирующем конструкторе, если данный нестатический элемент данных или базовый класс не обозначенмем-инициализатор-идентификатор (включая случай, когда нетмем-инициализатора-лист потому что конструктор не имеетт е р-инициализатор) и сущность не является виртуальным базовым классом абстрактного класса (10.4), то
если объект является нестатическим членом данных, который имеетскобки или равно-инициализаторобъект инициализируется, как указано в 8.5;в противном случае, если объект является вариантом члена (9.5), инициализация не выполняется;в противном случае объект инициализируется по умолчанию (8.5).Раздел 9.4.2 также разрешает инициализацию в классе неконстантных статических членов, если они помеченыconstexpr
спецификатор.
Так что же случилось с причинами ограничений, которые были у нас в C ++ 03? Должны ли мы просто принять «сложные правила компоновщика» или что-то еще изменилось, что облегчает реализацию?