What is the proper way to use static_assert in a non-instantiation template?

Viewed 96

For example I got some template classes:

template <typename T, typename = void>
struct A {
  void Print() {
    static_assert(false, "fall into unsupported Print function");
  }
};
// an instantiation if T is a unsigned type
template <typename T>
struct A<T, typename std::enable_if_t<std::is_unsigned<T>::value>> {
  void Print() {
    std::cout << "A<int>" << std::endl;
  }
};

but due to the standard:

If no valid specialization can be generated for a template definition, and that template is not instantiated, the template definition is ill-formed, no diagnostic required.

clang will immediately stop compiling and show failures, no matter if the template class gets instantiated or not, which is not what I meant to do.

I tried some other way like add a constexpr bool funtion to return false, but all failed.

So is there's any trick I can make the static_assert trigger only if the template class is instantiated?

1 Answers

If the expression inside static_assert depends on a template parameter, the assertion will be deferred until instantiation. You could, for example, define the following class template, deferred_false:

#include <type_traits> // std::false_type

template<typename>
struct deferred_false: std::false_type {};

Then, use it in the static_assert:

template <typename T, typename = void>
struct A {
  void Print() {
    static_assert(deferred_false<T>::value, "fall into unsupported Print function");
  }
};
Related