P0292R1 constexpr, если был включен, в пути для С++ 17. Кажется полезным (и может заменить использование SFINAE), но комментарий относительно static_assert
не сформирован, никакая диагностика, требуемая во ложной ветки, не пугает меня:
Disarming static_assert declarations in the non-taken branch of a
constexpr if is not proposed.
void f() {
if constexpr (false)
static_assert(false); // ill-formed
}
template<class T>
void g() {
if constexpr (false)
static_assert(false); // ill-formed; no
// diagnostic required for template definition
}
Я полагаю, что полностью запрещено использовать static_assert
внутри constexpr, если (по крайней мере, ложная/невозвращенная ветвь, но это на практике означает, что это не безопасная или полезная вещь).
Как это происходит из стандартного текста? Я не вижу упоминания static_assert
в формулировке предложения, а функции С++ 14 constexpr разрешают static_assert
(подробности в cppreference: constexpr).
Скрывается ли это новое предложение (после 6.4.1)?:
Когда выражение constexpr if появляется в шаблонизированном объекте, во время создания охватывающего шаблона или общей лямбды, отбрасываемый оператор не создается.
Оттуда я предполагаю, что также запрещено, не требуется диагностика, для вызова других функций constexpr (template), которые где-то по графику вызовов могут вызывать static_assert
.
Нижняя строка:
Если мое понимание верное, не делает ли это довольно жесткое ограничение безопасности и полезности constexpr if
, как мы должны были бы знать (из документации или проверки кода) о любом использовании static_assert
? Неужели мои заботы неуместны?
Update:
Этот код компилируется без предупреждения (clang head 3.9.0), но для моего понимания плохо сформирован, никакой диагностики не требуется. Действительно или нет?
template< typename T>
constexpr void other_library_foo(){
static_assert(std::is_same<T,int>::value);
}
template<class T>
void g() {
if constexpr (false)
other_library_foo<T>();
}
int main(){
g<float>();
g<int>();
}