Подтвердить что ты не робот

Шаблон класса для числовых типов

Как написать шаблон шаблона, который принимает только числовые типы (int, double, float и т.д.) в качестве шаблона?

4b9b3361

Ответ 1

Вы можете использовать черту типа std::is_arithmetic. Если вы хотите включить создание экземпляров класса только с таким типом, используйте его вместе с 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; //does not compile
}

Для более удобной в использовании версии enable_if и бесплатного добавления disable_if я настоятельно рекомендую прочитать эту замечательную статью по этому вопросу.

постскриптум В C++ метод, описанный выше, называется "Ошибка замены не является ошибкой" (большинство используют аббревиатуру SFINAE). Вы можете прочитать больше об этой технике C++ в Википедии или cppreference.com.

Ответ 2

Я нашел сообщения об ошибках, полученные из подхода template<typename T, typename = ...>, очень критические (VS 2015), но обнаружил, что a static_assert с одним и тем же типом также работает и позволяет мне указать сообщение об ошибке:

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