2009-10-26 12 views
9

ここには、保護されたメンバー変数を使用する古いコードベースがあります。これが良い考えであるかどうかは議論することができます。しかし、コードはgcc3でうまくコンパイルされていなければなりません。 私はそう派生クラス内のクラスの保護されたメンバーにアクセス

template <class Something> class Foo { 
public: 
// stuff... 
protected: 
    some::type x; 
} 

template <class Something> Bar : Foo<Something> { 
public: 
    void cleanup(); 
} 

とクリーンアップのメソッド宣言(のようにクラステンプレートはFooから保護部材Xを使用して派生テンプレートクラスのバーを持っている)これがないのx

template <class Something> void Bar<Something>::cleanup() { 
    doSomeThingCleanUpLike (x); 
} 

で行わものがありますgcc3で動作するはずですが、gcc4では動作しません。それを変更すると機能します

doSomeThingCleanUpLike (this->x); 

なぜそうですか?

+1

「テンプレートクラス」という用語は、しばしば混乱の原因となります。ものはクラスのテンプレートなので、正しい用語は "クラステンプレート"です。それはクラスではありません。私はあなたの質問を編集するだろうが、おそらくあなたが混乱した理由の一つです。 – MSalters

+1

"クリーンアップ"の関数定義に準拠していません。戻り値の型と "Bar"のテンプレート引数がありません。確かにそれはあなたのコードの中にありますか? –

+0

ありがとうlitb。私はそれを変えた。カフェインのレベルはそれを見つけ出すのに十分ではありませんでした。 「クラステンプレート」に変更されました。 そのテンプレートクラスまたはクラステンプレートが問題に影響しないかどうか。この用語はちょっと非公式に使われています。 – GeeF

答えて

13

派生クラスで使用される式xは、標準のルールでは、派生クラスのテンプレートパラメータに依存しません。このため、参照はテンプレート定義のコンテキストで行われ、使用/インスタンシエーションの時点では行われません。テンプレートのテンプレート基本クラスは可視であるように見えますが、それはテンプレートクラスであるため、使用される特定のインスタンス化には特殊テンプレートが必要なため、基本クラステンプレート定義を名前検索に使用することはできません。

式をthis->xに変更すると、従属式になります(クラステンプレートのthisは常にテンプレートパラメータに依存します)。つまり、インスタンス化のコンテキストでルックアップが発生し、ベースクラスが完全にわかっていてそのメンバーが可視になっていることを意味します。

+0

+1:*依存* * *依存しない*名前。 –

6

派生テンプレートを定義するとき、コンパイラは派生クラスが継承されたメンバを持っていることをコンパイラが知らないので、基本テンプレートクラスの名前しか知りません。コンパイラにメンバーの存在を伝えるために、あなたのようにthis->を使用してください。

実際には、それはthis questionの複製です。

+1

'this->'を追加することは儀式ではなく、依存しない名前を依存する名前に変換する方法であることに注意することが重要です。チャールズの答えを見てください。 –

+0

良いキャッチ、その質問_had_悪いタイトル。今修正されました。 – MSalters

関連する問題