2009-07-01 19 views
9

誰もが、依存宣言が従属する基底クラスから型名をインポートするために機能しないように見えるのは誰か知っていますか?それらはメンバ変数と関数で動作しますが、少なくともGCC 4.3では型のために無視されるようです。依存する基底クラスからの型へのアクセス

template <class T> 
struct Base 
{ 
    typedef T value_type; 
}; 

template <class T> 
struct Derived : Base<T> 
{ 
    // Version 1: error on conforming compilers 
    value_type get(); 

    // Version 2: OK, but unwieldy for repeated references 
    typename Base<T>::value_type get(); 

    // Version 3: OK, but unwieldy for many types or deep inheritance 
    typedef typename Base<T>::value_type value_type; 
    value_type get(); 

    // Version 4: why doesn't this work? 
    using typename Base<T>::value_type; 
    value_type get(); // GCC: `value_type' is not a type 
}; 

私はいくつかのレベルの継承を通して継承したいアロケータスタイルのtypedefのセットを持つ基本クラスを持っています。私が今までに見つけた最良の解決策は、上記のバージョン3ですが、なぜバージョン4が動作しないのか不思議です。 GCCはusing宣言を受け入れますが、それを無視するようです。

私はC++標準、C++ Progをチェックしました。 Lang。第3版[Stroustrup]、およびC++ Templates [Vandevoorde、Josuttis]のようなものであるが、use-declarationを従属基本クラス型に適用できるかどうかは明らかではない。

GCCのメーリングリストで、別の例(here is the same question being asked)が実際には答えられていないことが分かりました。 Askerは、 'typename'を他の場所で使っているのを見たことを示していますが、GCCはそれをサポートしていないようです。私はそれをテストするために利用可能な別のコンパイラを持っていない。

+0

準拠しているコンパイラに対して(自分の意見では)コンパイルする必要があるコードを投稿します。テンプレートの使い方を投稿してください。 –

+0

私はすべての関連情報は上記と考えています。バージョン1〜4はMSVC 9で動作します.MSVC 9は、非一段階の名前解決(つまりインスタンス化時)を持っています。バージョン2と3のみGCC 4.3で動作します。バージョン4が無効であるべき理由はわかりませんが、GCCはそれを受け入れません。 使い方については、これがどのようにインスタンス化されるかは実際問題ではありません。私はちょうどコンパイルするテンプレート宣言を取得しようとしています。上記のコードは、はるかに複雑なコンテナアダプタを単純化したものです。 –

+0

ここにコードを投稿するときに、コンパイルするためにコードを編集する必要があるとは思わないでください。 –

答えて

8

リチャードコーデンが指摘するように2003規格が批准された後、この問題はC++ Standard Core Language Defect Reportsで対処されました:How do the keywords typename/template interact with using-declarations?

決議案(2003年4月、 改訂2003年10月):

新しいを追加段落の末尾に 7.3.3 [namespace.udecl]:

使用宣言で キーワードtypenameを使用し、を指定すると(12.7.2 [temp.dep])、 using宣言によって導入された名前は typedef-name(7.1.3 [dcl.typedef])として扱われます。

このテキストは、10月15日からSecond Editionの標準に表示されていないようですbug 14258で説明したように、2003年

GCCはまだ、この解像度を実装していません。

- ----- Comment#3 Giovanni Bajoから2004-02-27 12:47 [返信] ------- 問題は私たちのUSING_DECLが である "typename"を で記録していないということです実際には というタイプのものです。これは暗黙的な型名 拡張のおかげで の仕事をしていましたが、私は信じています。

重複bug 21484は、 'using typename'がComeauおよびIntelコンパイラで機能することを示しています。 MSVCはすべての名前を依存するものとして扱うので、そのコンパイラの構文は不要です(しかし許可されます)。 GCC 4で


Fixed。2011年12月13日の7日!

+1

これはバグですが、最近は比較的最近のことですので、gccを難しくしてはいけないと思います。次の中核的な問題は、用語の変更点「http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#11」を強調しています。これはC++ '03標準に移行しました。 –

+0

ありがとう、リチャード、それは私が探していた正確なリンクです! –

-1

Base :: value_typeのtypedefを宣言する前に、Baseのテンプレートにアクセス指定子(public/protected/private)を含めなかった。その結果、デフォルトでprivateになり、Baseから派生したクラスではアクセスできなくなります。

+5

彼は基本/派生型を構造体として定義しているため、そのメンバーはデフォルトで* public *でありプライベートではありません。 – luke

関連する問題