using宣言は、外部スコープ宣言を隠すが、引数依存ルックアップ(ADL)を抑制しない通常の宣言として機能します。
using B::f
を実行すると、基本的に何も変更されません。あなたは単にB::f
をローカルスコープで再宣言します。ローカルスコープには既に表示されています。 ADLがA::f
を見つけることを妨げないので、A::f
とB::f
のあいまいさが発生します。
using A::f
を実行する場合、ローカル宣言A::f
は、外側宣言B::f
を非表示にします。したがって、B::f
は表示されなくなり、修飾されていない名前検索によってもはや検出されません。 A::f
のみが見つかりました。これはもはやあいまいさがないことを意味します。
ADLを抑制することはできません。あなたのケースの引数は
A::X
タイプなので、
A::f
という関数は、修飾されていない名前
f
のADLによって常に検出されます。それを考慮から除外することはできません。つまり、あいまいさを生じることなく
B::f
を考慮に入れることはできません。唯一の方法は、修飾された名前を使用することです。
@リチャードスミスがコメントに正しく記載しているように、ADLを抑制することができます。 ADLは、関数呼び出しで関数名自体を後置式として使用する場合にのみ使用されます。それ以外の方法でターゲット関数を指定すると、ADLが呼び出されます。例えば
、関数ポインタの初期化はB::f
が呼び出される上記の例ではADL
void g(A::X x)
{
void (*pf)(A::X) = &f;
pf(x);
}
を受けません。さらには、関数名の周り()
の単なるペアがADLを抑制するのに十分である、すなわち
void g(A::X x)
{
(f)(x);
}
はすでにそれがB::f
を呼び出す作るのに十分です。
出典
2013-07-06 17:48:25
AnT
コールサイトでADLを抑制するには、関数名をカッコで囲みます。 '(f)(x)'を使うとあいまいさが修正されます。 –
明らかに、上記のコード抜粋のどれでも 'B :: f;'を使う必要はありません – Tony