Предположим, у вас есть шаблон функции, который вызывает другую функцию, которая может быть или не быть функцией constexpr
в зависимости от параметра шаблона. C ++ позволяет объявить вызываемого constexpr
в любом случае, если хотя бы одно возможное создание экземпляра дает constexpr
.
Например:
template <class T>
constexpr bool bar() { return true; }
template <>
bool bar<int>() { return false; }
template <class T>
constexpr bool foo() { return bar<T>(); }
foo<short>();
foo<int>(); // not a constexpr, but compiles anyway
Это позволяет получить хорошую степень гибкость, так что мы можем производить вызовы функций constexpr
, когда это возможно, но в противном случае возвращаться к не-constexpr.
Однако я заметил, что такая же гибкость не распространяется на C ++ 17 if constexpr
.
Например:
if constexpr(foo<short>()) { /* do something */ }; // works
if constexpr(foo<int>()) { /* do something */ }; // won't compile, bar<int>() is not constexpr!
Я сталкивался с ситуациями, когда я хотел бы использовать if constexpr
, чтобы избежать накладных расходов времени компиляции на создание экземпляров определенных шаблонов, но вычисляемое выражение может не всегда быть constexpr
в зависимости от параметров шаблона. Есть ли какая-то причина, по которой if constexpr
не просто «деградирует» до оператора, отличного от constexpr if
, если условное выражение зависит от параметра шаблона, а шаблон создает экземпляр без constexpr? Так же, как с поведением constexpr
функций?
Это просто произвольное упущение в стандарте (т.е. никто не думал, что это будет полезно), или есть более фундаментальная причина, по которой if constexpr
не может "деградировать" до не-constexpr if
?