2016-03-13 13 views
8

Ich habe eine Klasse, um einige Merkmale eines Typs zu beschreiben.Spezialisieren statisch constexpr Datenelement

template<typename T> 
struct my_traits 
{ 
    static constexpr int some_trait = 0; 

    static constexpr T min() { return std::numeric_limtis<T>::min(); } 
    static constexpr T max() { return std::numeric_limits<T>::max(); } 
}; 

Ich möchte my_traits::some_trait spezialisieren, aber wenn ich versuche:

template<> constexpr int my_traits<int>::some_trait = 1; 

Der Compiler beschwert sich, dass my_traits::some_trait bereits einen Initialisierer hat. Natürlich kann ich es spezialisieren, indem Sie:

template<> 
struct my_traits<int> 
{ 
    static constexpr int some_trait = 1; 

    // min and max 
}; 

aber dann habe ich alle anderen Funktionen neu zu definieren, obwohl sie genau das gleiche sein wird.

Also wie kann ich spezialisieren my_traits<int>::some_trait ohne zu wiederholen min und max?

+0

AFAIK das ist nicht möglich. Eine 'constexpr'-Variable muss in ihrer Deklaration initialisiert oder konstruiert werden. –

+6

'statisch constexpr int some_trait = mein_helfer :: value;' –

+1

Sie könnten versuchen, es von einer 'constexpr'-Funktion oder Dienstklasse zu initialisieren, die auf den Typ' int' spezialisiert ist – Niall

Antwort

5

Es gibt mehrere Möglichkeiten, dies zu tun. @Piotr Skotnicki und @Niall erwähnten das Initialisieren durch einen Helfer, der spezialisiert werden kann. Im Allgemeinen, restrukturieren Sie einfach Ihren Code, so dass Sie einige Klassen oder Funktionen spezialisieren können, und verwenden Sie dann (durch Zusammensetzung oder Vererbung) die Spezialisierungsteile nach Teilen, die Sie nicht spezialisieren müssen.

Als Beispiel für eine Alternative zu den Kommentaren, hier ist eine spezialisierte Basis:

#include <iostream>                                               
#include <limits> 

template<typename T> 
struct my_specializing_traits 
{ 
    static constexpr int some_trait = 0; 
}; 

template<> 
struct my_specializing_traits<int> 
{ 
    static constexpr int some_trait = 1; 
}; 

Jetzt können Sie es einfach in einen gemeinsamen Teil Unterklasse:

template<typename T> 
struct my_traits : 
    public my_specializing_traits<T> 
{ 
    static constexpr T min() { return std::numeric_limits<T>::min(); } 
    static constexpr T max() { return std::numeric_limits<T>::max(); } 
}; 

Im Folgenden wird es verwendet (es gibt 0 und 1 aus)

int main() 
{ 
    std::cout << my_traits<char>().some_trait << std::endl; 
    std::cout << my_traits<int>().some_trait << std::endl; 
} 
Verwandte Themen