メンバクラスは、listのテンプレート引数にできない?

[戻る]
しん 2007/01/18(木) 16:15:30
メンバクラスは、listのテンプレート引数にできないかを伺っても宜しいでしょうか?
下のコードで実験したら、VC++7.1ではコンパイルできますが、とあるg++だと
「 'iterator' was not declared in this scope」という文法エラーが出ました。
( ISO規格外? VC++で出来たのは たまたま? )

解決の為に散々試行錯誤しましたが、力尽きた為 皆さんに伺おうと思った次第です。
どうか宜しくお願い致します。

実験環境:WinXP Pro+最新SP、VC++7.1(非SP)、とあるg++ ver.4(クロスコンパイラ)

----------------------- ここから -------------------------
#include <list>

template< int T >
struct A
{
  // メンバクラスB。Aの外に出すと、何故かg++でもコンパイル出来る
  // が、A専用の為、Aのメンバクラスとして宣言したい...。
  struct B{};

  struct B_list : std::list< B >
  {
    void f()
    {
      iterator i; // 文法エラーが起きる場所
    }
  };
};
----------------------- ここまで -------------------------

しん 2007/01/18(木) 16:36:25
更に調べたら、下のようにすれば良い事が分かりました。

修正前:  iterator i; // 文法エラーが起きる場所
修正後:  typename std::list< B >::iterator i; // 文法エラーが起きる場所

長ったらしいですが、これが規格通りの文法なら従わざるを得ませんね...。

yoh2 [E-Mail] 2007/01/18(木) 22:23:05
std::list<B>は、正確には::std::list<::A<T>::B>となります。テンプレートパラメータTが
こっそり存在しているのです。
そのため、std::list<B>内で定義されている(と期待される)型を使うのにtypenameが必要になるわ
けです。

ちなみに、

    typename B_list::iterator

でもOKのはず。
頻繁に使うのならtypedefして使うという手もありますね。

    typedef typename B_list::iterator iterator;

    iterator i;
    ...

しん 2007/01/19(金) 21:23:31
[[解決]]
なるほど!そうだったのですね。よ〜く分かりました。
typename B_list::iteratorでもOKでした。より単純な分、こっちの方が良いですね。

どうも有難うございました!

古いスレッドには追加発言できません。