Class template for numeric types

前端 未结 2 709

How do I write a class template that accepts only numeric types (int, double, float, etc.) as template?

相关标签:
2条回答
  • 2020-12-08 07:20

    You can use the std::is_arithmetic type trait. If you want to only enable instantiation of a class with such a type, use it in conjunction with std::enable_if:

    #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
    }
    

    For a version of enable_if that's easier to use, and a free addition of disable_if, I highly recommend reading this wonderful article on the matter.

    p.s. In C++, the technique described above has a name called "Substitution Failure Is Not An Error" (most use the acronym SFINAE). You can read more about this C++ technique on wikipedia or cppreference.com.

    0 讨论(0)
  • 2020-12-08 07:30

    I found the error messages received from the template<typename T, typename = ...> approach highly cryptic (VS 2015), but found that a static_assert with the same type trait also works and lets me specify an error message:

    #include <type_traits>
    
    template <typename NumericType>
    struct S
    {
        static_assert(std::is_arithmetic<NumericType>::value, "NumericType must be numeric");
    };
    
    template <typename NumericType>
    NumericType add_one(NumericType n)
    {
        static_assert(std::is_arithmetic<NumericType>::value, "NumericType must be numeric");
        return n + 1;
    }
    
    int main()
    {
        S<int> i;
        S<char*> s; //doesn't compile
    
        add_one(1.f);
        add_one("hi there"); //doesn't compile
    }
    
    0 讨论(0)
提交回复
热议问题