this はつけるべきか
C++ (や Java その他の言語)において, メンバ変数や関数のアクセスに this->
をつけるべきか否か, という疑問があり, 調べてみた.
this をつけるべきかどうかについてはコーディング規約や好みの問題で議論されている(た). が, 何か決定的な違いがあったような気がしてもやもやしていた.
次の点は, 個人やプロジェクトの嗜好ではなく技術的にはっきりと意識すべき違いをもたらす.
#include <iostream> struct X { void hoge () { std::cout << "hoge" << std::endl; } }; template <typename T> struct A { void foo () { T x; x.hoge(); } }; template <typename T> struct B : public A<T> { void bar () { foo(); } }; /* ※1 */ int main () { B<X> b; b.bar(); return 0; }
x.cpp: In member function ‘void B<T>::bar()’: x.cpp:8: error: there are no arguments to ‘foo’ that depend on a \ template parameter, so a declaration of ‘foo’ must be available x.cpp:8: error: (if you use ‘-fpermissive’, G++ will accept your \ code, but allowing the use of an undeclared name is deprecated)
B
これを解決する手段は:
foo()
の呼び出しを書き換えてthis->foo()
にするfoo()
の呼び出しを書き換えてA<X>::foo()
にする- using A<X>::foo; 宣言 (using-declaration) を追加する.
また, foo がテンプレート引数の typename T に依存していれば, thisをつけなくても名前を見つけてくれるらしい. フ..フクザツな!
これは, テンプレート化された基底クラス内の名前へのアクセスするために知っておくべき方法らしい. 実は, 以前読んだ Effective C++ に書いてあった (やっぱり手元に置いてたまに見返さないといけないなぁ).
有名な本に載っているくらいだから, 有名な事実なんだろうけど, 検索でひっかかりにくかったので, こんなエントリを書いてみました, と.
あと, 仮想関数とか継承関係の問題がほかにもあったような気がするのだけど思い出せない. 気のせいかもしれない.
《参考》
- http://www.i-drift.com/?p=63
Effective C++ 原著第3版 (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES)
- 作者: スコット・メイヤーズ,小林健一郎
- 出版社/メーカー: ピアソン・エデュケーション
- 発売日: 2006/04/29
- メディア: 大型本
- 購入: 29人 クリック: 411回
- この商品を含むブログ (186件) を見る
追記
cppll_novice にて, どんぴしゃなスレッドが見つかりました...
- http://ml.tietew.jp/cppll/cppll_novice/thread_articles/965
- http://womble.decadentplace.org.uk/c++/template-faq.html#two-phase
- http://womble.decadentplace.org.uk/c++/template-faq.html#base-lookup
ADL (argument dependent lookup) とか two-phase name lookup が関係するらしい, と. ふむふむ.