Suppose you have a function template that calls another function, which may or may not be a constexpr function depending on a template parameter. C++ allows the callee to be declared constexpr anyway, as long as at least one possible instantiation produces a constexpr.
For example:
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 This allows a nice degree of flexibility so that we can produce constexpr function calls whenever possible, but fall back to a non-constexpr otherwise.
However, I notice the same flexibility does not extend to the C++17 if constexpr.
For example:
if constexpr(foo<short>()) { /* do something */ }; // works if constexpr(foo<int>()) { /* do something */ }; // won't compile, bar<int>() is not constexpr! I've encountered situations where I'd like to use if constexpr to avoid the compilation time overhead of instantiating certain templates, but the evaluated expression may not always be a constexpr depending on template parameters. Is there some reason that if constexpr doesn't just "degrade" to a non-constexpr if statement if the conditional expression depends on a template parameter and the template instantiates to a non-constexpr? Just like with the behavior of constexpr functions?
Is this simply an arbitrary omission in the standard (i.e. nobody thought it would be useful), or is there some more fundamental reason why if constexpr can't "degrade" to a non-constexpr if?