2017-11-16 10 views
-1

テンプレートを使用して、 'MyClass'というクラスを実装する必要があります。テンプレートタイプの導出

template<class T> 
class MyClass 
{ 
public: 


      T var1; 
      T1 var2; 
     }; 

var1とvar2の2つのメンバー変数があります。クラステンプレート引数 'T'が基本型(float、double、またはlong doubleなど)である場合、変数var1とvar2の両方の型はテンプレート引数と同じである必要があります。上記の例ではT1 = Tです。

しかし、テンプレート引数がstd::complex<T>であれば、私はC++ 11でそれを実装する方法

T var1; 
std::complex<T> var2; 

を持っていると思いますか?

+3

では部分的な特殊化のための仕事のようですね。 – Quentin

+0

[基本型のテンプレート特殊化](https://stackoverflow.com/questions/45244809/template-specialization-for-fundamental-types)の可能な複製 –

+1

算術演算でも 'std :: complex'でもない場合はどうなりますか? – AndyG

答えて

6

可能な解決策は、(あなたがTは基本的なタイプであることを確認したい場合は、正しいタイプ

template <typename T> 
struct myTypeTraits 
{ using type = T; }; 

template <typename T> 
struct myTypeTraits<std::complex<T>> 
{ using type = T; }; 

MyClass

template <typename T> 
class MyClass 
{ 
    using T0 = typename myTypeTraits<T>::type; 

    T0 var1; 
    T var2; 
}; 

なっ抽出するために、単純なタイプの特性を定義することができたり算術を意味しますか?)、少し複雑です。

可能な方法は、タイプは次の宣言(なしの一般的な定義)でmyTypeTraitsを変更し、デフォルトのブール値std::complex

template <typename> 
struct isComplex : public std::false_type 
{ }; 

template <typename T> 
struct isComplex<std::complex<T>> : public std::true_type 
{ }; 

であれば(trueまたはfalseを)言ってタイプの特性を定義しています

template <typename T, bool = std::is_fundamental<T>::value, 
         bool = isComplex<T>::value> 
struct myTypeTraits; 

次に2つの専門、ファンダメンタルズのための最初のものとの複合体タイプの第1

template <typename T> 
struct myTypeTraits<T, true, false> 
{ using type = T; }; 

template <typename T> 
struct myTypeTraits<std::complex<T>, false, true> 
{ using type = T; }; 

MyClassクラスはstd::stringイコール残っていますが(例で)でそれをインスタンス化しようとすると、今の誤差を与えます。

次は、完全なコンパイルの例

#include <complex> 
#include <type_traits> 

template <typename> 
struct isComplex : public std::false_type 
{ }; 

template <typename T> 
struct isComplex<std::complex<T>> : public std::true_type 
{ }; 

template <typename T, bool = std::is_fundamental<T>::value, 
         bool = isComplex<T>::value> 
struct myTypeTraits; 

template <typename T> 
struct myTypeTraits<T, true, false> 
{ using type = T; }; 

template <typename T> 
struct myTypeTraits<std::complex<T>, false, true> 
{ using type = T; }; 

template <typename T> 
class MyClass 
{ 
    public: // public to check with the static_assert() 
     using T0 = typename myTypeTraits<T>::type; 

    private: 
     T0 var1; 
     T var2; 
}; 

int main() 
{ 
    MyClass<int>     mi; // compile 
    MyClass<std::complex<float>> mc; // compile 
    // MyClass<std::string>   ms; // compilation error 

    static_assert(std::is_same<int, decltype(mi)::T0>{}, "!"); 
    static_assert(std::is_same<float, decltype(mc)::T0>{}, "!"); 
} 
+0

優秀!答えをありがとう。しかし、私はちょうど私が再びテンプレートのパラメータに依存するメンバ関数を持つ必要があることに気づいた。これについても、あなたは優雅なソリューションを提供していただけますか? – Soo

+0

@Soo - 違いがたくさんある場合は、(MyQuassによって提案されているように) 'MyClass'全体を部分的に専門化することを検討する必要があります。しかし、 "テンプレート関数に依存するメンバ関数"のヘルプが必要な場合は、残念ですがあまりにも一般的です。具体的な例を挙げて質問を修正したり、別の質問で質問したりすることをお勧めします。 – max66

関連する問題