2008/08/10

C++でクラステンプレートを使った既定クラスへのメンバアクセス

次のようなコードを書きました。
template<typename T>
class B {
public:
int _i;
};

template<typename T>
class D : public B<T> {
public:
void f(const int i) {_i = i;}
};

int
main()
{
D<int> aD;
aD.f(5);
return 0;
}
これをg++ 3.4.6でコンパイルしようとしたら、
baz.cc: In member function `void D::f(int)':
baz.cc:10: error: `_i' was not declared in this scope
と言われて、悩みました。クラステンプレートを使わなければ問題ないのになぁ、と。

同じことではまっていたNão Aqui!さんのBlogを通じて最終的に、C++FAQ liteの該当章へたどり着きました。うえー、確かに nondependent name だけどさー。

正しくは、
  • this->で修飾してdependent nameにする
  • using B::_i;でlook upを明確化する
  • B::_i;にする。が、関数の場合仮想選択機構が働かなくなるので、注意
とのことです。

ISO/IEC 14882draft(June 2008)の「14.6 Name resolution」も読んでみましたが「いや、確かにそう読めるけど...」という感じで、これを頭に叩き込んでいたととしても、実際にはまってみるまでは、気がつかなかったと思います。

やっぱりC++は難しいな。くー。

0 件のコメント:

コメントを投稿