2011-01-07 32 views
1

名前の "* Pack"に相当するクラスがたくさんあるとします。例えば、私がクラスMooを持っているなら、私はMooPackを持っています、もし私がFooを持っていれば、私もFooPackを持っています。テンプレート引数の文字列化と非文字化け

私は

template <class X, class XPack> 
XPack packify(X input){ 
    ... 
} 

フー

からFooPackを返すC++テンプレート関数がテンプレート引数を指定せずにこれを実行することが可能ですしたいですか?現時点では、これは以下のように実行する必要があります。

Moo moo; 
MooPack mooppey = packify<Moo, MooPack>(moo); 

それが唯一の醜いテンプレートの指定ビットが実際にされていない、離れての#defineを使用してから離れて行くが、できることが、武のテンプレート引数が必要な場合どちらも最高の解決策ではありません。

方法はありますか、またはC++ 0xを待たなければなりませんか?

答えて

5

ムーを指定する必要はありません。ムーパックは、あなたのために引数を推論するためです。しかし、MooPackをMooの内部でtypedefまたは入れ子にしたクラス(Packと呼ばれる)にすることをお勧めします。この場合、typename X :: Packをテンプレートの中に簡単にアクセスできます。

class Moo { 
public: 
    class Pack { 
     ... 
    }; 
}; 
template<typename T> typename T::Pack packify(T t) { 
    ... 
} 

// usage 

Moo m; 
Moo::Pack p = packify(m); 
+0

ああ、実際には1つの引数しか指定できないと思うのですが(2つの引数はちょっと醜いです)。そのネストされたクラスのことは素晴らしいアイデアですが、私は既存のクラス宣言を変更することはできません。 – kamziro

+2

'* Pack'クラスをネストする必要さえないので、入れ子になったtypedefを提供するだけです。使用方法は上記の例と同じです。これはかなり一般的なパターンです(「メタ機能」と呼ばれます)。 –

1

DeadMGによって答えはすでにあなたは(それが第二の代わりに、最初のテンプレートパラメータの場合)、それがautomaticaly推測することができるよう明示的にパラメータの型を指定する必要はありません述べたように。あなたは(STDだと思う::にiterator_traitsを)あなたはクラス間のリンクを形成するための型宣言を変更することはできません、私はそのための特徴ルートを提案するだろうと述べているので:

template<typename T> struct pack_traits; 
template<> struct pack_traits<Moo> { typedef MooPack Pack; }; 
...//traits for other packifable classes 

template<typename T> pack_traits<T>::Pack packify(T val){...} 
... 
Moo moo; 
MooPack mooppey = packify(moo); 

あなたはせずに関数を呼び出すことができますこの方法は、テンプレートの引数を手動で指定し、クラス自体を変更する必要はありません。

関連する問題