2013-08-21 4 views
9

Ich möchte Validierer für Zahlen verschiedener Arten erstellen (integer, floating points) z.B .:Template-Struktur Spezialisierung für Integral-/echte Typen

typename number_validator<T>::type validator; 

ich nützliche Merkmale im std heißt is_integral und is_floating_point gefunden. Wie kann ich diese Merkmale verwenden, um die Vorlage zu spezialisieren (es ist ein struct)?

edit: Ich bin für so etwas wie folgt aussehen:

template<typename T, typename Enabled> 
struct number_validator {}; 

template<typename T> 
struct number_validator<T, typename enable_if<is_floating_point<T>::value, T>::type> 
//this doesn't work.. 
{ 
    typedef floating_point_validator type; 
}; 
+1

Was macht Ihr "Validator"? –

+0

wird es Zahlen validieren. Ich würde den ':: type' vorbereiten, um typedefs für einige spezifische Klassen mit allgemeiner Schnittstelle zu sein (aber nicht Unterklassen) – Kiel

+0

Was ich frage, ist, wie man die Zahlen validieren möchte? Sicherlich gibt es einen einfacheren Weg. –

Antwort

12

Dies könnte das sein, was Sie suchen, das heißt Tag Dispatching:

template<typename T, bool = is_integral<T>::value> 
struct number_validator {}; 

template<typename T> 
struct number_validator<T, true> 
{ 
    typedef integral_validator type; 
}; 

template<typename T> 
struct number_validator<T, false> 
{ 
    typedef floating_point_validator type; 
}; 

Dies setzt voraus, dass Sie wirklich auf Zahlen arbeiten, so dass die Typen sind immer entweder integral oder Punkt schweben.

1

Sie haben nicht einmal die in diesem Fall benötigen, könnten Sie eigentlich spezialisieren nur die Vorlagen wie diese.

Dies wird Ihren Nummernprüfer für jeden Typ spezialisieren, dies erfordert, dass Sie alle Integral- und Gleitkommatypen auflisten. Man könnte auch so etwas tun:

#include <type_traits> 
#include <iostream> 
template<class T> 
typename std::enable_if<std::is_floating_point<T>::value,T>::type func(T t) { 
    std::cout << "You got a floating point" << std::endl; 
    return t; 
} 

template<class T> 
typename std::enable_if<std::is_integral<T>::value,T>::type func(T t) { 
    std::cout << "You got an Integral" <<std::endl; 
    return t; 
} 

int main() { 
    float f = func(1.0); 
    int a = func(2); 
} 
+2

Ich möchte nicht alle Integral-und Float-Typen, die ich kenne .. – Kiel

+0

Dies könnte tatsächlich funktionieren, aber können Sie entfernen "auto" (C++ 03 hier)? Nun, Sie definieren Funktionen, die vales zurückgeben, ich würde lieber den Code verwenden, den ich in meiner Frage geschrieben habe (als Variablendeklaration), aber Ihre Lösung würde ausreichen, wenn kein 'auto' verwendet würde. – Kiel

+0

Ich könnte automatisch entfernen, aber Sie haben Ihre Frage C++ 11 und is_integral ist C++ 11 – aaronman

1

Sie diese mit Integer-Zahlen tun können:

template <typename T, bool isIntegral = std::is_integral<T>::value> 
struct number_validator 
{ 
    typedef WhatEverType type; 
}; 

template <typename T> 
struct number_validator<T, true> 
{ 
    typedef WhatEverTypeInt type; 
}; 

Die zweite Spezialisierung gewählt werden, wenn es eine ganze Zahl ist, aber ich weiß nicht, was tun, wenn es ein Gleitkomma oder ein anderer Typ ist.