Static_assert (false) on the constexpr if branch

This question shows that

template <class T> struct X { static_assert(false); }; template <> struct X <int> {}; 

(unexpectedly) makes the program poorly formed, no diagnostics are required (even if X never created). Its essence is that if there is no imaginary template instance of the main template that is valid, then the program is poorly formed. Having a real specialization does not change this, nor fancy tricks like static_assert(sizeof(T) != sizeof(T)) or anything else.

If you look at the standard, this applies to all templates: class templates and function templates. Thus, this also makes the program poorly formed (again, unexpectedly, and even if foo never called):

 template <class T> auto foo() { static_assert(false); } template <> auto foo<int>() {} 

C ++ 17 introduced constexpr if . So the question is, is it really or not:

 template <class T> auto foo() { if constexpr (!std::is_same_v<T, int>) { static_assert(false); } } 

I would guess that since constexpr if instances are created (the correct word?) Only on the basis of the condition, now we have the correct foo (foo) creation, which is well formed because it does not contain a branch with static_assert . However, both clang and gcc (trunk versions on godbolt ) refuse to compile the code.

So is this really an invalid program?


Real life example:

I recently wrote this answer :

 template < typename REAL_T, std::size_t N1, std::size_t N2, std::size_t N3> void solve(std::array< REAL_T, N1 * N2 > & A, std::array< REAL_T, N3> & b) { if constexpr (N3 == std::max(N1, N2)) wrap::internal< N1, N2, N3 >(A, b); else static_assert(N3 == std::max(N1, N2), "invalid 3rd dimmension"); // was tempted to write this instead which certainly seems resonable //static_assert(false, "message"); } 
0
source share

Source: https://habr.com/ru/post/1275782/


All Articles