Программа с конструктором "noexcept", принятым gcc, отклонена clang
код:
struct T { T() {} };
struct S
{
T t;
S() noexcept = default;
};
int main()
{
// S s;
}
g++ 4.9.2 принимает это без ошибок или предупреждений, однако отчет clang 3.6 и 3.7 для строки 7:
error: exception specification of explicitly defaulted default constructor does not match the calculated one
однако, если строка S s;
не комментируется, g++ 4.9.2 теперь сообщает:
noex.cc: In function 'int main()':
noex.cc:12:7: error: use of deleted function 'S::S()'
S s;
^
noex.cc:7:5: note: 'S::S() noexcept' is implicitly deleted because its exception-specification does not match the implicit exception-specification ''
S() noexcept = default;
^
какой компилятор подходит для исходного кода?
Справочная информация:
g++ даже позволяет добавить в main
:
std::cout << std::is_constructible<S>::value << 'n';
что выходы 0
. Я столкнулся с этой проблемой при использовании clang для компиляции некоторого сложного кода, который сильно использовал шаблоны, SFINAE и noexcept. В этом коде S
и T
являются классами шаблонов; поэтому поведение зависит от того, какие типы S
был создан экземпляр С. Clang отклоняет его с этой ошибкой для некоторых типов, тогда как g++ разрешает его, и SFINAE работает на основе is_constructible
и подобные черты.
1 ответов
зависит от версии стандарта, с которым Вы консультируетесь.
N3337 [dcl.fct.защита.по умолчанию] / p2:
явно-дефолтная функция [...] может иметь явное исключение-спецификация только если он совместим (15.4) с исключение-спецификация о неявном заявлении.
Что делает ваш исходный код плохо сформированные.
Это было изменено на проблема CWG 1778 читать (N4296 [dcl.fct.защита.по умолчанию]/Р3):
Если функция, которая явно по умолчанию объявлена с исключение-спецификация это несовместимо (15.4) со спецификацией исключения в неявном объявлении, тогда
- если функция явно по умолчанию при первом объявлении, она определяется как удаленная;
- в противном случае, программа плохо сформированные.
Что означает, что конструктор теперь просто определен как удаленный. (В приведенную выше формулировку включены изменения, внесенные N4285, документ после C++14, вносящий некоторые изменения очистки, предназначенные для чисто редакционного характера. Версия N3936 по существу такая же.)
предположительно GCC реализует разрешение CWG1778, а Clang-нет.