2016-07-30 6 views
7

mapped_typeがテンプレートクラスの内部クラスであるstd :: mapを宣言するための正しい構文を助けてください。テンプレートクラス 'inner classのマップイテレータの正しい構文ですか?

以下のコードで#if /#elseブロックを見つけてください。 "#if 1"ブロックには、内部クラスInnerを含むテンプレートクラスOuterがあります。 Outerは、mapped_typeがInner型のstdマップを取る関数Funcを定義します。

#include <map> 

#if 1 
template<typename C, typename T> 
class Outer 
{ 
    public: 
     Outer(const C& c, const T& t){} 
     virtual ~Outer(){} 

     class Inner 
     { 
      public: 
       Inner(){} 
       Inner(T t){} 
       virtual ~Inner(){} 

      protected: 
       T mT; 
     }; 

     void Func(std::map<C, Inner>& rMap); 

    protected: 
     std::map<C, Inner> mMap; 
}; 

template<typename C, typename T> 
void Outer<C, T>::Func(std::map<C, Outer::Inner>& rMap) 
{ 
    std::map<C, Inner>::iterator iter; 

    for (iter = rMap.begin(); iter != rMap.end(); ++iter) 
    { 
     mMap[iter->first] = iter->second; 
    } 
} 

#else 

class Outer 
{ 
    public: 
     Outer(const int& i, const double& d){} 
     virtual ~Outer(){} 

     class Inner 
     { 
      public: 
       Inner() : mD(0){} 
       Inner(const double d) : mD(d){} 
       virtual ~Inner(){} 

      protected: 
       double mD; 
     }; 

     void Func(std::map<int, Inner>& rMap); 

    protected: 
     std::map<int, Inner> mMap; 
}; 

void Outer::Func(std::map<int, Inner>& rMap) 
{ 
    std::map<int, Inner>::iterator iter; 

    for (iter = rMap.begin(); iter != rMap.end(); ++iter) 
    { 
     mMap[iter->first] = iter->second; 
    } 
} 

#endif 

int main() 
{ 
    return 0; 
} 

コンパイルがこのラインすなわち、STD ::マップのイテレータの宣言で外::のFunc(...)で失敗します。

std::map<C, Inner>::iterator iter; 

私が試したが、何を把握することはできませんコード行に間違いがあります。

"#else"ブロックには、類似した性質の非テンプレートコードが含まれています。このコードはコンパイルされます。

コンパイルエラーとg ++バージョンは以下のとおりです。

>g++ main.cpp 
main.cpp: In member function ‘void Outer<C, T>::Func(std::map<C, Outer<C, T>::Inner, std::less<_Key>, std::allocator<std::pair<const C, Outer<C, T>::Inner> > >&)’: 
main.cpp:31: error: expected ‘;’ before ‘iter’ 
main.cpp:33: error: ‘iter’ was not declared in this scope 

>g++ --version 
g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-11) 
Copyright (C) 2010 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

は、任意の助けてくれてありがとう。

+0

'typename std :: map :: iterator iter;' – nshct

+0

[templateとtypenameのキーワードをどこに入れて、なぜ入れる必要がありますか?](http://stackoverflow.com/questions)/610245/where-and-why-do-do-do-do-have-the-template-and-typename-keywords) – Oktalist

答えて

9

InnerはテンプレートOwner<C, T>のメンバーであるため、dependent nameになります。これにより識別子iterator(この場合はstd::map<C, Inner>のメンバー)が従属名にもなります。

これはルールに従って、キーワードtypenameを使用するためにあなたを強制的に:

typename std::map<C, Inner>::iterator iter; 
~~~^~~~~ 

コンパイラはそれがないので、自分のクラスの内部の特定の構築物は何を意味するかを確認することはできませんので、これはありますテンプレート(クラステンプレートと関数テンプレートの両方)の定義内

を、意味0:まだCTのために使用される正確な種類を知っていますいくつかの構成は、あるインスタンス化ごとに異なる場合がある。特に、タイプおよび表現は、タイプテンプレートパラメータのタイプおよび非タイプテンプレートパラメータの値に依存し得る。

typenameキーワードは、アクセスしているシンボルが実際にタイプエイリアス/タイプであることをコンパイラに伝えるために使用されます。

+1

私はそこにある知恵のフォントに驚いています。ありがとうございました。 – StoneThrow

+0

正直言って、あなたが指摘したリンクの説明は私の頭の上になりました。あなたがこのシナリオに精通しているなら、簡単に説明することができますか? 「typenameキーワードは、アクセスしているシンボルが本当にタイプエイリアス/タイプであることをコンパイラに伝えるために使用されます」と言うとき、この文脈では「シンボル」とは何ですか?内部クラス?私の説明の解析に基づいて、私はこの解決策がこのような状況(内部クラス)に必要な理由は不明ですが、 "非内部"クラスでは必須ではありません。あなたが深い説明を持っていることを感謝しますが、そうでなければ心配はありません。ありがとうございました。 – StoneThrow

関連する問題