実引数依存の名前探索
なお、std::swapを特殊化するという方法もあるが、特殊化しようとする型がテンプレートの場合に対応できない(自由関数で部分特殊化はできない)ために完璧ではない。
なお、std名前空間での多重定義は現在認められていない(特殊化は認められている)。
一般にADLに過度に依存すると意味の問題が起こる。あるライブラリL1がL1::foo(T)が呼び出される前提で未修飾のfoo(T)という呼出を行っているとする。別のライブラリL2も同様にfoo(T)の呼出を行っている。2つのライブラリを同時に使うと、L1::foo(T)が呼ばれなければならない場面でL2::foo(T)が呼ばれるなど互いに意図するとおりにならない可能性が生じる。しかし、L1が内部でL1::foo(T)とし、L2も内部で同様にL2::foo(T)と共に完全に修飾していれば、このようなADLの心配は全く起こらない(逆にADLを起こしたい場合はusing L1::foo; foo(x);のように書く)。
ADLは自由関数(クラスのメンバ関数でない関数)もクラスのインタフェースとして扱う。つまり、名前空間に制限をもたらし、ADLの必要がなければ完全に修飾された名前を用いる必要があることを意味する。逆の例として、標準C++ライブラリは2つの値の交換にstd::swapを修飾なしで呼ぶことが挙げられる。
別の案として、std::swapをユーザに多重定義させるという方法がある。次のコードは挙動が異なる。
完全修飾した名前で呼ぶ場合:
予めusingしておく場合:
ただし、aとbはN::Aという型とする。
N::swap(N::A&, N::A&)が存在した場合、後者ではそれが呼ばれるが、前者では呼ばれない。さらに細かいことを言えば、仮に両方とも定義されていたら、前者ではstd::swap(N::A&, N::A&)が呼ばれるが、後者ではどちらにするか曖昧になる(名前の探索に失敗しコンパイルエラーになる)。