4

テンプレート化されたクラスのメンバー関数内で次の問題が発生しました。

#include <map>
using std::map;
template <typename A,typename B>
class C {
  public:
    B f(const A&,const B&) const;
  private:
    map<A,B> D;
};
template <typename A,typename B>
B C<A,B>::f(const A&a,const B&b) const {
   map<A,B>::const_iterator x = D.find(a);
   if(x == D.end())
     return b;
   else
     return x->second;
}

これを g++ でコンパイルすると、次のエラーが発生します。

Bug.C: In member function 'B C<A,B>::f(const A&, const B&) const':
Bug.C:12: error:expected ';' before 'x'
Bug.C:13: error: 'x' was not declared in this scope

ただし、クラスと関数のテンプレート化されていないバージョンを作成すると、A と B の両方が int になり、問題なくコンパイルされます。なぜ「;」が必要なのか想像できないので、エラーは少し不可解です。「x」の前。

4

3 に答える 3

13

がありませんtypename:

typename map<A,B>::const_iterator x = D.find(a);

「template」および「typename」キーワードをどこに、なぜ入力する必要があるのか​​をお読みください。. typenameここで必要な理由は、ABがテンプレート パラメーターであるためです。つまり、 の意味はとが何であるかに::const_iterator 依存します。人間には名前からこれがイテレータ型であることは明らかですが、コンパイラにはこれが型なのかデータ メンバーなのかなどはわかりません。ABconst_iterator

コンパイラは、テンプレートがインスタンス化される前に最初のパスで構文チェックを行いtypename、コンパイラに型として解析することを知らせることによって追加しますmap<A,B>::const_iterator

また、C ++には特別なルールがあります(リンクされた質問から恥ずかしそうに盗まれました):

テンプレートの宣言または定義で使用され、テンプレート パラメーターに依存する名前は、該当する名前の検索で型名が検出されるか、名前がキーワード typename によって修飾されない限り、型を指定しないと見なされます。

を追加しない場合typename、コンパイラはそれが型ではないと想定する必要があります。

于 2013-08-09T21:02:46.090 に答える
2

typename型を参照し、テンプレート パラメーターに依存する修飾名の前に必要なキーワード がありません。

typename map<A,B>::const_iterator x = D.find(a);
于 2013-08-09T21:04:46.190 に答える
1

追加する必要がありますtypename

typename map<A,B>::const_iterator x = D.find(a);

説明:
typename後に続く名前を型として扱う必要があることを示します。それ以外の場合、名前は非型を参照するものとして解釈されます。

于 2013-08-09T21:03:44.237 に答える