2013-01-12 16 views
20

Jak napisać szablon klasy, który akceptuje tylko szablony liczbowe (int, double, float itd.) Jako szablon?Szablon klasy dla typów liczbowych

+0

@KonradRudolph Wykonaj chcesz również poprawić tytuł? Jestem zdezorientowany, jeśli OP naprawdę oznacza typy lub faktycznie oznacza stałe tych typów. – pmr

+0

@ pmr Nie zrobiłem (ale zrobiłem to teraz), dobry połów. Jestem całkiem pewien, że OP oznacza typy, jeśli nie z innego powodu, że nie można używać typów nie-integralnych jako szablonów nie typu i że pytanie nie ma sensu na początku, gdy mówimy o szablonach nie typu. –

+0

@KonradRudolph Tak, mam na myśli typy. – djWann

Odpowiedz

26

Możesz użyć cechy typu std::is_arithmetic. Jeśli chcesz tylko umożliwić konkretyzacji klasy z takiego typu, używać go w połączeniu z 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 
} 

Dla wersji enable_if, który jest łatwiejszy w obsłudze i darmowego dodatku disable_if, bardzo polecam czytania this wonderful article (lub cached version) w tej sprawie.

+2

Możesz zostawić 'typename Dummy ='. Ponadto bardzo polecam używanie tutaj [Wheels] (https://bitbucket.org/martinhofernandes/wheels), czyni to kod znacznie prostszym: 'template >>' –

+0

@ KonradRudolph, Masz rację, dzięki. Dodam link do jego wpisu 'enable_if' do dalszego czytania. – chris

+0

@KonradRudolph, Usunięcie 'Dummy' spowodowało, że nie został skompilowany, ale nie jestem z nim zbyt doświadczony, więc nie mogę powiedzieć, jak to powinno wyglądać, poza tym. Zdałem sobie jednak sprawę, że mogę usunąć bezsensowne imię. – chris

3

znalazłem komunikaty o błędach odbierane od podejścia template<typename T, typename = ...> bardzo tajemniczym (VS 2015), ale okazało się, że static_assert tego samego typu cecha działa również i pozwala mi podać komunikat o błędzie:

#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

Pewnie. Byłoby miło dodać tę wiadomość tutaj. – kyb

Powiązane problemy