2015-12-22 9 views
5

EDIT:私が休暇に入ったときに提案されたソリューションをテストする機会は実際にはありませんでした。クラステンプレートを担当していたので、クラステンプレート自体で定義された型を使用する必要がなくなりました。クラステンプレートの特殊なクラスの内部型を使用

皆様のおかげで彼らの助けになりました。一言で言えば


- と私の文言を修正すること自由に感じ、テンプレートは、まだ私にはブードゥー教のビットです - 私は(protectedstructまたはクラス内で定義された#typedefを使用することができるかどうかを知る必要があり私の専門クラスのテンプレート。たとえば:

これはクラステンプレートです:

私は完全に T = VALのために特化する必要が
template<typename T> 
class A : public C<T> 
{ 
protected: 
    struct a_struct { /* Class template implementation, doesn't depend on T */ }; 
    void foo(a_struct a); 
}; 

template<> 
class A<VAL> : public C<VAL> 
{ 
    void foo(a_struct a) 
    { 
     // My implementation of foo, different from the class template's 
    } 
}; 

私はこのような何かを行う場合は、しかし、コンパイラはそのa_structを不平を言います私の専門クラスでは定義されていません。私は専門化し、クラステンプレートから継承したが、それは...乱雑になった。

私はいくつかの解決策を見ましたが、それらのすべてがクラステンプレートの変更に関連していました。これは簡単にはできません(別のチーム)。

思考?

+0

テンプレートの 'typename'の必要性が説明されているので、他の多くの質問を見てください:http://stackoverflow.com/questions/610245/where-and-why-do-i-have-to -put-the-template-and-typename-keywords – JSF

+0

申し訳ありませんが、私は最初あなたの質問に誤解しました。基本クラスの型を継承するのではなく、独自の特殊化されていないバージョンを継承したいとします。 – JSF

+0

オリジナルを "変更"せずに偽のベースを作成できると思います。オリジナルを継承し、擬似ベースを育てるクラスを作成すると、擬似ベースは型定義をオリジナルの保護領域から独自の保護領域に盗むことができます。その後、その偽ベースを専門化の真の基盤として使用します。 – JSF

答えて

1

それは美しいではありませんが、あなたはこのようにそれを行うことができます。

template<typename T> 
class C 
{ 

}; 

template<typename T> 
class A : public C<T> 
{ 
protected: 
    friend A<int>; 
    // ^^^^^^ 
    struct a_struct { /* Class template implementation, doesn't depend on T */ }; 
    void foo(a_struct a); 
}; 

template<> 
class A<int> : public C<int> 
{ 
    using a_struct = typename A<void>::a_struct; 
    // ^^^^^^ 
    void foo(a_struct a) 
    { 
     // My implementation of foo, different from the class template's 
    } 
}; 
4

いいえ、あなたはクラステンプレートのあなたの専門分野における主要なテンプレート宣言のメンバーを使用することはできません。それは、本質的に、テンプレートクラスの特殊化は、テンプレート引数が特殊化に一致するときに適用される完全に新しいクラステンプレートを宣言するためです。

あなたの例のように何かをしたい場合は、しかし利用できる2つのオプションがあります。

  • あなたはテンプレートクラスのメンバー機能を特化することができます。これは実際に特殊なメンバー関数の1つ(または少なくともメンバー関数の数が限られている)の場合に便利です。
  • メンバ(-type)の宣言を共通の基底クラスに持ち込むことができます。

クラステンプレート自体を変更できないように編集したので、メンバー関数を特化するのが最適な方法です。

メンバ関数を専門の簡略化されたexampleのみ

template< class T> 
class Printer 
{ 
public: 
    struct Guard {}; 
    void DoPrint(const T& val) 
    { 
     Guard g; 
     (void)g; 
     std::cout << val << '\n'; 
    } 
}; 

struct Duck {}; 

template<> 
void Printer<Duck>::DoPrint(const Duck& val) 
{ 
    Guard g; 
    (void)g; 
    std::cout << "Some duck\n"; 
} 

ここでGuardのみこのタイプは、一次及びDoPrint()の特殊な実装の両方に利用可能であることを実証するために使用されます。

0

または、特殊なテンプレートのstruct a_structをデフォルトのものと同じ機能で再宣言してください。

すべての特殊なテンプレートを注入する必要があるので、うまくいきません。しかし、それは今私が考えることができるものです。

関連する問題