2016-03-13 4 views
8

私はある型の特性を記述するクラスを持っています。Specialize静的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(); } 
}; 

私はmy_traits::some_traitを専門にしたいが、私はしようとすると:

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

コンパイラはmy_traits::some_traitはすでに初期化子を持っていることを文句を言います。

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

    // min and max 
}; 

をその後私は、彼らはまったく同じになるにもかかわらず、他のすべての機能を再定義する必要があります。もちろん、私はやってそれを特化することができます。

my_traits<int>::some_traitminmaxを繰り返さずに、どのように特化できますか?

+0

AFAIKこれはできません。 'constexpr'変数は、その宣言で初期化または構築されなければなりません。 –

+6

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

+1

'int'型に特化した' constexpr'関数またはユーティリティクラスから初期化することができます – Niall

答えて

5

いくつかの方法があります。 @Piotr Skotnickiと@Niallは、特殊化できるヘルパーを使って初期化することについて言及しました。一般的には、コードを再構成して、いくつかのクラスや関数を特殊化し、特殊化する必要のないパーツで特殊化パーツを(合成または継承によって)使用することができます。コメントへの代替の一例として、

は、ここに専門ベースである:

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

今、あなただけの共通部分にそれをサブクラス化することができます

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

以下は、使用を示し(0と1を出力します)

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