Ответ 1
TL; DR
В С++ 14 это явно не разрешено, хотя в 2011
оно выглядело так, как будто этот случай явно разрешен. Неясно, что для С++ 11 это подпадает под правило as-if, я не верю, что это происходит, поскольку оно изменяет наблюдаемое поведение но этот вопрос не был уточнен в проблеме, о которой я упоминал ниже.
Подробнее
Ответ на этот вопрос изменился с меняющимся статусом LWG issue 2013, который открывается с помощью
Предположим, что определенная функция не помечена как constexpr в стандартным, но что в некоторой конкретной реализации возможно записать его в пределах ограничений constexpr. Если теги реализации такая функция, как constexpr, заключается в нарушении стандартного или является ли оно соответствующим продолжением?
В С++ 11 было неясно, разрешило ли это правило as-if это, но предложение orignal явно разрешило его после его принятия, и мы можем видеть ниже в отчете об ошибке gcc, на который ссылаюсь, это было сделано командой gcc.
Консенсус, позволяющий это изменить в 2012 году, и предложение изменилось, а в С++ 14 это несоответствующее расширение. Это отражено в стандартном разделе проекта С++ 14 17.6.5.6
[constexpr.functions], который гласит:
[...] Реализация не должна объявлять какую-либо стандартную библиотечную функцию подпись как constexpr, за исключением тех, где она явно требуется. [..]
и хотя строгое чтение этого, похоже, оставляет некоторое пространство для маневра для обработки встроенного неявно, как если бы это было constexpr, мы можем видеть из следующей цитаты в этом вопросе, что целью было предотвращение расхождения в реализациях, поскольку идентичный код мог вызывают различное поведение при использовании SFINAE (основное внимание):
Некоторая озабоченность, выраженная при представлении полного комитета для голосования к статусу WP, что этот вопрос был разрешен без достаточного думал о последствиях для расходящихся реализаций библиотек, поскольку пользователи могут использовать SFINAE для наблюдения за другим поведением в противном случае идентичный код.
Из отчета gcc bug [С++ 0x] sinh vs asinh vs constexpr видно, что команда полагалась на ранее предложенную разрешение LWG 2013, в котором говорится:
[...] Кроме того, реализация может объявить любую функцию constexpr, если это определение функции удовлетворяет ограничения [...]
при решении вопроса о том, разрешено ли это изменение для математических функций в режиме строгого соответствия.
Насколько я могу судить, это станет соответствовать, если это мы получили предупреждение в строгом режиме соответствия, то есть с помощью -std=c++11 -pedantic
или если он был отключен в этом режиме.
Заметьте, я добавил комментарий к отчету об ошибке, пояснив, что разрешение изменилось с тех пор, как эта проблема была первоначально исправлена.
Джонатан Вакели указал на в другом вопросе более поздний обсуждение, и он кажется вероятным, что отчет об ошибке gcc будет вновь открыт для решения этой проблемы соответствия.
Как насчет встроенных функций
Внутренние параметры компилятора не охватываются стандартом, и насколько я могу судить, они должны быть освобождены от этого правила, поэтому используйте:
static constexpr double a = __builtin_cos(3.);
должно быть разрешено. Этот вопрос возник в отчете об ошибке, и мнение Дэниела Крюглера было:
[...] Функции библиотеки и другие внутренние функции, вероятно, можно рассматривать как исключений, поскольку они не обязаны быть "объяснимыми" посредством нормальные языковые правила.