You are saying that static_assert would not trigger here, correct? That makes sense to me, but it's not what is in the proposal [1] - see the "Not proposed" section.
[1] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p029...
[1] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p029...
template<class T>
class foo;
template<>
class foo<int> {
static_assert(false, "bad");
};
template<>
class foo<float> {};
template<class T>
foo<T> foo_fn(T v) {
if constexpr (std::is_same<T, int>::value) {
return foo<int>{};
}
else if constexpr (std::is_same<T, float>::value) {
return foo<float>{};
}
else {
return foo<T>{};
}
}
foo_fn(1.0); // <-- does not trigger static assert
foo_fn(1); // <-- triggers static assert
This is consistent with the wording of the proposal. template<>
class foo<int> {
static_assert(false, "bad");
};
Reason: "false" is not a dependent name, so the compiler is allowed to check the static_assert when the template is being declared.(Of course since this is a full specialization, there are no dependent names.)
See C++14 Standard §14.6.2 (Dependent Names) or http://en.cppreference.com/w/cpp/language/dependent_name (not sure how accurate that page is, though).
P.S: It might compile with Microsoft's Visual Studio, but only because that compiler doesn't implement two-phase name lookup, effectively turning every name into a dependent name.
Also this dependent name behavior of static_assert seems to be a precedent for always checking static_assert in constexpr if.