2012-04-13 21 views
0

似たような質問がたくさんあることを認識していますが、私の問題を解決するものは見つかりませんでした(読んでください: printVariable(mapping.begin());テンプレート化されたクラスの引数を持つテンプレート付き関数

これは動作しますが、今私はまた、AA map<string, int*>を持ってしたい:私は次の操作を行うことができますmap<string, bool*> mappingをお持ちの場合は今

void printVariable(map<string, bool*>::iterator it) 
{ 
    cout << it->first << " " << *(it->second) << endl; 
} 

:私の場合)

に私は、次の機能を持っていますその人をすることができる同じので、私は、私はprintVariable機能変更考え出し:

template <typename T> 
void printVariable(map<string, T*>::iterator it) 
{ 
    cout << it->first << " " << *(it->second) << endl; 
} 

をただし、これはエラー(GCC)をコンパイルできます:

error: variable or field 'printVariable' declared void 
error: expected ')' before 'it' 

私は機能をオーバーロードすることで、この非常に簡単回避することができますね。しかし、私は上記がうまくいかない理由を知りたいです。

EDIT2:削除されたテキストは、適切なソリューションが間違っていたと主張

+0

イテレータはテンプレート型の従属型なので、型名指定子をパラメータに追加する必要がありますか? 'void printVariable(typename map :: iterator it)' –

答えて

5

あなたは依存名明確にするためにtypenameを言っている:

template <typename T> 
void printVariable(typename map<string, T*>::iterator it) 
//     ^^^^^^^^ 

しかし、これは推論文脈ではないことに注意してくださいので、このフォームを非常に便利ではありません。など

template <typename Iter> 
void printVariable(Iter it) 
{ /* ... */ } 

そのように、あなたはまた、非標準のコンパレータまたはアロケータとマップ、および順不同マップをキャプチャなど


いっそのこと、単にテンプレートパラメータ全体のイテレータを作ります

ここでは、最初の状況で推論可能なコンテキストがない理由を簡単に考えてみましょう。次のfooの呼び出しでは、どのようにしてTを推測する必要がありますか?

template <typename T> void foo(typename Bar<T>::type); 

template <typename T> struct Bar { typedef char type; }; 
template <> struct Bar<int>  { typedef int type; }; 
template <> struct Bar<double> { typedef int type; }; 

foo(10); // What is T? 
+0

いいえ、最初の変種は動作しません。 –

+0

最初の変種は実際には機能しません(私はすでにそれを試していたと思います)。しかし、2番目の変種は動作します!試してみるようなことをやっていないのを馬鹿に感じてください:) – user1302914

+0

誰かが最初の変種がうまくいかない理由を説明できますか?私は実際にその変種(それがうまくいけば)を好みます。なぜなら、関数のシグネチャは、関数の引数が何であるべきかについてもっとはっきりしているからです(あるいは、私はそのようなことを考慮してはいけませんか?)。 – user1302914

関連する問題