2008/6/1 日曜日

C++テンプレートのFAQ

Filed under: Programing — chokkan @ 18:44:29

あるコードを書いていて,Visual C++ 2008ではコンパイルが通るのに,g++では通らないケースで悩む.Visual C++ 2008はtypenameキーワードまわりが緩く,g++では付け忘れを大量に指摘されるのが常だ.そんなVisual C++ 2008のぬるま湯に浸かっているためか,今日は以下のようなコードがコンパイル出来なくてびっくりした.

template <class T>
class base
{
public:
    T var;
};

template <class T>
class derived : public base<T>
{
public:
    void set(const T& x)
    {
        var = x;    // error: `var' undeclared.
    }
};

int main(int argc, char *argv[])
{
    derived<int> x;
    x.set(2);
    return 0;
}

Visual C++ 2008ではエラー・警告無しだが,g++ 3.4では,”error: `var’ undeclared” というエラーが,派生クラス (derived) の var = x; という箇所で発生する.変数varは基底クラスbaseでpublicメンバとして定義されており,derivedはbaseをpublic継承しているので,deriveクラス内部からvarにアクセスできるのは,当然のはず.それがg++では,認められない.

こういうエラーは検索キーワードを見つけるのが難しいが,ほどなく C++ Template FAQ というページに辿りつく.これによると,テンプレート化されている派生クラスが,同じくテンプレート化されている基底クラスのメンバをアクセスするには,this->var = x; または,base<T>::var = x; みたいにしなければならない.このルールは,メンバ変数,メンバ関数のどちらにも当てはまるらしい.テンプレート化されていなければ,こういうことは起きないし,Visual C++では問題なくコンパイルが通っていたので,ちょっと驚きだった.

C++のコードは,フィーリングで何となく書けているけど,正確なコードを書くのは大変なんだなぁと改めて実感.

コメントはまだありません »

コメントはまだありません。

この投稿へのコメントの RSS フィード。 TrackBack URL

コメントする

HTML convert time: 0.590 sec. Powered by WordPress ME