2016-03-13 17 views
8

Mam klasę opisującą niektóre cechy danego typu.Specjalizuję się w statycznym członku danych constexpr

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(); } 
}; 

chcę specjalizują my_traits::some_trait ale gdy próbuję:

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

Kompilator narzeka, że ​​my_traits::some_trait ma już inicjator. Oczywiście mogę specjalizują się go robi:

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

    // min and max 
}; 

ale potem trzeba przedefiniować wszystkie inne funkcje, choć będą dokładnie takie same.

Więc jak mogę wyspecjalizować my_traits<int>::some_trait bez powtarzania min i max?

+0

AFAIK to nie jest możliwe. Zmienna "constexpr' musi zostać zainicjowana lub zbudowana w deklaracji. –

+6

'static constexpr int some_trait = my_helper :: value;' –

+1

Można go zainicjować za pomocą funkcji 'constexpr' lub klasy narzędziowej, która specjalizuje się w typie' int' – Niall

Odpowiedz

5

Istnieje kilka sposobów, aby to zrobić. @ Piotr Skotnicki i @Niall wspomnieli o inicjalizacji za pośrednictwem jakiegoś pomocnika, który może być wyspecjalizowany. Ogólnie rzecz biorąc, po prostu zrestrukturyzuj swój kod, abyś mógł specjalizować się w niektórych klasach lub funkcjach, a następnie używał (według kompozycji lub dziedziczenia) części specjalizowanych według części, których nie potrzebujesz specjalizować.

Jako przykład alternatywę dla komentarzach, tutaj jest specjalizujący podstawa:

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

Teraz można tylko podklasy go w części wspólnej:

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(); } 
}; 

Poniżej przedstawiono kiedyś (wyświetla 0 i 1)

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