Search code examples
c++templatestype-safetytype-level-computation

How to make `enable_if` a hard requirement


This answer contains the following code:

#include <type_traits>

template<
    typename T, //real type
    typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type
> struct S{};

int main() {
   S<int> s; //compiles
   S<char*> s; //doesn't compile
}

The requirement that T satisfy is_arithmetic can easily be defeated, though, by specifying an arbitrary second type argument for the template S, e.g. S<char*, void>. Is there a way to foreclose this possibility?


Solution

  • Is there a way to foreclose this possibility?

    Yes, there is as shown below. In particular, we can make the second parameter a non-type parameter with a default.

    template<
        typename T,
        //make the second parameter a non-type parameter with default 
        typename std::enable_if<std::is_arithmetic<T>::value, nullptr_t>::type N = nullptr 
    > struct S{};
    
    int main() {
       S<int> s; //compiles 
        //S<int, void> S2;  //DOESN'T COMPILE 
       //S<int, 1> S3;     //DOESN'T COMPILE
       
    }