Как написать шаблон шаблона, который принимает только числовые типы (int
, double
, float
и т.д.) в качестве шаблона?
Шаблон класса для числовых типов
Ответ 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
}