Search code examples
c++sfinaetype-traitsstatic-assert

static_assert if expressions is constexpr


I want to create a class template

template <class T>
class X {
  // here I'll use T::value (among other things)
};

T::value will often be a constexpr static variable, but not always. T::value has to be positive value, so I want to let people know it during compilation, when possible.

If T::value was always constexpr, I'd add static_assert like

static_assert(T::value > 0, "need positive number");

Is it possible to add this static_assert only for cases when T::value is constexpr?


Solution

  • We can write an is_valid template function (come up with a better name) with two overloads:

    template <typename T, int N = T::value>
    constexpr bool is_valid(int) {
        return N > 0;
    }
    
    template <typename T>
    constexpr bool is_valid(...) {
        return true;
    }
    

    The first overload will only be valid if T::value is a constant expression, otherwise it will be SFINAEd out. The second overload is valid no matter what, so we disambiguate the overload with a dummy int parameter.

    Now we test it like so:

    static_assert(is_valid<T>(0), "need positive number");
    

    Live Demo