Объявленный пользователем конструктор по умолчанию + инициализаторы класса! = Предоставленный пользователем конструктор?

В документации Clang четко объясняется, что

Если класс или структура не имеют определяемого пользователем конструктора по умолчанию, C ++ не позволяет вам создавать по умолчанию его константный экземпляр, как это ([dcl.init], p9)

Причина в том, что если объект const не инициализирован правильно, он не может быть изменен позже. В следующем коде есть только конструктор по умолчанию, объявленный пользователем для Test, но все его члены имеют инициализаторы класса,

#include<iostream>

class Test
{
public:
    Test() = default;
    void print() const { std::cout << i << "\n"; }
private:
    int i = 42;   // will propagate to the default constructor!
};

int main()
{
    Test const t; // <-- Clang chokes on the const keyword, g++ does not
    t.print();    // prints 42
}

так что обоснование того, что пользователь также предоставляет конструктор по умолчанию, кажется мне излишним. И действительно, g ++ 4.8.1 компилирует его без проблем (сильный пример в Интернете) > Clang ‹= 3.2 - нет.

Вопросы: почему комбинации полных инициализаторов класса + объявленного пользователем конструктора по умолчанию недостаточно для создания по умолчанию константного объекта? Есть ли исправление для стандарта C ++ 14?

ОБНОВЛЕНИЕ: может ли кто-нибудь попробовать Clang 3.3 / 3.4, чтобы узнать, исправлено ли это по сравнению с Clang 3.2?


person TemplateRex    schedule 05.07.2013    source источник
comment
Я думаю, что это ошибка / баг в Clang, и g ++ правильно принимает код.   -  person Jerry Coffin    schedule 06.07.2013
comment
@JerryCoffin Есть какая-нибудь стандартная цитата, которая может подойти к этому? Я спрашиваю, потому что без классового инициализатора Стандарт говорит, что Clang прав.   -  person TemplateRex    schedule 06.07.2013
comment
Не совсем цитата, но к N3337 формулировка уже была изменена, поэтому это требование отпало. Учитывая, что он входит в стандарт, я полагаю, что называть это ошибкой или ошибкой, вероятно, немного неточно, но на данный момент я думаю, что большинство компиляторов в основном игнорируют C ++ 11 как таковой и занимаюсь более новыми проектами.   -  person Jerry Coffin    schedule 06.07.2013
comment
@JerryCoffin - значит, DR, помеченный как активный, уже включен в спецификацию, вопреки тому, что говорится в моем ответе? С каким решением?   -  person Johannes Schaub - litb    schedule 06.07.2013
comment
@ JohannesSchaub-litb: ТБХ, я не совсем уверен - формулировка, цитируемая в DR, похоже, исчезла, но это может быть побочным эффектом другого редактирования, и они все еще работают над другими изменениями, чтобы иметь больше конкретно с этим DR (или нет - не возвращаясь к протоколу собрания, я не уверен, почему все изменилось на то, что есть сейчас).   -  person Jerry Coffin    schedule 06.07.2013
comment
@ abyss.7 эээ, как я могу заглянуть в будущее? ;-)   -  person TemplateRex    schedule 20.02.2014
comment
@TemplateRex Я только что прочитал вопросы о такой ситуации на Meta - и ответы рекомендуют закрыть старый вопрос, если он не так информативен. Совершенно без обид.   -  person abyss.7    schedule 20.02.2014
comment
@ abyss.7 без обид, меня просто позабавили ;-)   -  person TemplateRex    schedule 20.02.2014
comment
Как указано в моем ответе здесь: stackoverflow.com/a/47368753/852254, это решено в clang в 3.9.0 .   -  person David Stone    schedule 18.11.2017


Ответы (1)


Да, это известная проблема. См. http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#253. Это еще не было исправлено в спецификации.

person Johannes Schaub - litb    schedule 05.07.2013
comment
+1 и принято. Приятно знать, что это на радаре. - person TemplateRex; 06.07.2013
comment
Есть ли у вас случайно доступ к Clang 3.3 / 3.4, чтобы проверить, сохраняется ли проблема? - person TemplateRex; 06.07.2013
comment
@TemplateRex К сожалению, с clang 3.4 (транк 184647) это все еще проблема. :( - person Ali; 06.07.2013