以下のC++コードでは、double
パラメータの場合はfoobar
が最初に定義され、次にFoo
の場合は1つのパラメータとして再度定義されます。両方ともグローバル名前空間内で定義されています。別の名前空間内からのC++グローバル名前空間アクセス
one
名前空間内には、さらにfoobar
のオーバーロードが定義されており、単一のパラメータはBar
です。このバージョンのfoobar
では、foobar
へのdouble
引数(42.0)の非修飾呼び出しは失敗します。 foobar
への同様の呼び出しは、今度はdouble
引数を持つ(::)スコープ解決演算子で修飾されていますが、成功します。
一方、タイプFoo
のfoobar
への非修飾呼び出しは成功します。スコープ解決演算子によって修飾されたのFoo
引数の呼び出しも成功します。
なぜ2つのシナリオが異なる動作をするのですか?私はgcc 4.7とclang ++ 3.2の両方を使用しています。
struct Foo {};
struct Bar {};
double foobar(double x) { return x; }
Foo foobar(Foo f) { return f; }
namespace one {
Bar foobar(Bar b) {
//foobar(42.0); // error: can't convert to Bar
::foobar(42.0);
Foo f;
foobar(f); // no problem
::foobar(f);
return b;
}
};
最後の文に加えて:修飾されていない名前の検索は、一致する* name *が見つかるとすぐに停止します。ローカルのスコープを考慮し、そこに名前が見つからない場合のみ、上位スコープとグローバルスコープを検索します。 – Xeo
ありがとうございました。 ADLへのリンクは事を明確にします。 – user2023370
@ Xeo:これは、 'foobar(f)'への呼び出しが 'foobar(Bar b)'を見つけて失敗することを意味しないでしょうか? – user2023370