一般的には問題ではないので、より単純なオプションmember = value;
が推奨されます。場合によっては、ローカル変数にあいまいさがあり、this->
プレフィックスで修飾することができますが、より良いアプローチは、あいまいさを完全に回避することです。
ただし、それが問題となるいくつかのコーナーケースがあります。仮想関数を処理する場合、修飾名(type::member
)を使用すると、ランタイムディスパッチが無効になり、レベルの最終的なオーバーライドtype
が呼び出されるようになります。
struct base {
virtual int f() { return 1; }
};
struct derived : base {
virtual int f() { return 2; }
void g() {
std::cout << f() << "\n";
std::cout << derived::f() << "\n";
}
};
struct mostderived : derived {
virtual int f() { return 3; }
};
int main() {
mostderived d;
d.g(); // 3 2
}
テンプレートクラスと継承を処理する場合、ルックアップは2つのフェーズで実行されます。最初のフェーズでは、依存しない名前を解決する必要があります。非修飾名は非依存名であるため、場合によっては、またはのいずれthis->
かtype::
で修飾する必要があり、上記の区別が引き続き適用されます。追加の資格は、名前を依存させるのに役立ちます:
template <typename T>
struct derived : T {
void g() {
// std::cout << f() << "\n"; // Error, cannot resolve f() [*]
this->f(); // Ok, pick final overrider at runtime
derived::f(); // Ok, pick overrider here: base::f()
}
};
struct base {
virtual int f() { return 1; }
};
struct mostderived : derived<base> {
virtual int f() { return 3; }
};
int main() {
mostderived d;
d.g(); // 3, 1
}