これは、名前の一部として名前空間を常に明示的に含めることを常に提唱している他のいくつかの回答に対する対位法よりも回答ではありません。時々、これは悪い考えです。場合によっては、手元のタイプに特化した名前が存在する場合はそれを使用しますが、それ以外の場合は標準で提供される代替名を使用します。
典型的な例として、ソート関数を考えてみましょう。タイプTのオブジェクトを並べ替える場合、アイテムを交換することになります。スペシャルswap(T &, T&)
が存在する場合はそれを使用しますが、template <class T> std::swap
そうでない場合は使用します。
明示的に使用するスワップのフルネームを指定しようとする場合は、どちらか一方を指定する必要があります。特殊なバージョンを指定し、それ自体を定義していないタイプに対してソートをインスタンス化します。スワップは失敗します。そうでない場合は、を指定std::swap
し、並べ替えるタイプ用に特別に提供されたスワップを無視します。
using
ただし、このジレンマから抜け出す方法を提供します。
using namespace std;
template <class T>
mysort(/* ... */ ) {
// ...
if (less(x[a], x[b])
swap(x[a], x[b]);
// ...
}
これで、Tが見つかった名前空間にが含まれている場合、swap(T &, T&)
引数依存のルックアップを介して見つけられ、上記で使用されます。存在しない場合は、表示されるようになっているstd::swap
ため、検出(および使用)さusing namespace std;
れます。
余談ですが、ちょっとした変更を加えるだけで、using namespace x;
ほぼ完全に無害にすることができると思います。現在のところ、その名前空間の名前が現在のスコープに導入されています。それらの1つがたまたま現在のスコープに存在する名前と同じである場合、競合が発生します。もちろん、問題は、名前空間に含まれるすべてを把握しているとは限らないため、ほとんどの場合、少なくともある程度の競合の可能性があることです。
using namespace x;
変更は、現在のスコープを囲むスコープを作成し、その名前空間からその周囲のスコープに名前を導入したかのように扱うことです。それらの1つがたまたま現在のスコープで導入された名前と同じである場合でも、競合は発生しません。他のブロックスコープと同様に、現在のスコープの名前は周囲のスコープから同じ名前を隠します。
私はこれについてあまり詳しく考えていなかったので、解決するのにもっと注意が必要ないくつかのコーナーケースがあることは間違いありませんが、一般的な考え方はおそらく多くのことをかなり簡単にするだろうと思います。