2012-04-06 15 views
2

ネストされたテンプレートとテンプレートの特殊化に問題があります。次のクラスを考える:テンプレートを特殊化<typename T、テンプレート<typename> class U>

小さなテンプレートクラス

template<class U> 
class T { 
public: 
    T(){} 
    virtual ~T(){} 

}; 

そして、ネストされたテンプレートのいくつかの種類

template<typename T, template<typename> class U> 
class A { 
public: 
    void foo() 
    { 
     std::cerr << "A generic foo"; 
    } 
}; 

と小さなmain.cppに

int main(int argc, const char *argv[]) 
{ 
    A<int,T> *a = new A<int,T>; 
    a->foo(); 

    //This wont work: 
    A<double,T*> *b = new A<double,T*>; 
    b->foo(); 

    return 0; 
} 

今私が必要Uがポインタの場合の特殊化:

A<double,T*> *b = new A<double,T*>; 
    b->foo(); 

これを行うには?私のような何か試してみました:

template<typename T, template<typename> class U> 
class A< T, U* > 
{ 
public: 
void foo() 
{ 
    std::cerr << "A specialized foo"; 
} 
}; 

をしかしT*は意味がありませんので、それだけで、何をする抱き合わせていることはできません

A.h:18:16: Error: Templateargument 2 is invalid 
+0

あなたは混乱しているようです。 –

+0

@ildjarn:いいえ、それはうまくいきます。なぜなら、 'A'は1つのパラメータを持つテンプレート型のものを期待しているからです。 'T'はその請求書に適合します。 – bitmask

+0

@bitmask:ああ、まったく正しい、私は明らかに注意を払っていなかった。 – ildjarn

答えて

0

で解決します。それは適切な型でもなく、追加のパラメータを必要とするテンプレートと一致しません。 UT*を表す場合、U<int>は何ですか?あなたはおそらくT<int>*を意味しますが、それはあなたの宣言と一致しないので、そのタイプをAに接続する方法はありません。

あなたは私の頭の上から、これを回避する方法を尋ねたので、このようなものです。

私はExpanderを呼び出し、これにはデフォルトでそれを設定することになる、Aに第三テンプレート引数を受け入れる:

template <typename T> struct Expander { 
    typedef T type; 
}; 

その後、Aを呼び出すときに、あなたが

A<int,T> normal; 
A<int,T,PtrExpander> pointer; 

を言うことができます

template <typename T> struct PtrExpander { 
    typedef T* type; 
}; 

およびAは:

template<typename T, template<typename> class U, template <typename> class E = Expander> class A { 
    typedef typename E<U<Your_Args_to_U> >::type; 
+0

しかし、Tはテンプレートを表していますか? – user988017

+0

@ user988017:はい、 'T *'はありません。 'T'は型ではないので(テンプレートです)、そのポインタを持つことはできません。 C++ *はこの非公式の表記を許可することができますが、そうではありません。 – bitmask

+0

私は...これを回避する最も簡単な方法は何ですか? – user988017

関連する問題