using namespace stdしたくなった時、そこに確固たる理由があるならば、次の2点について検討すること。
- スコープを限定する。
- 対象とする識別子を限定する。
ある程度C++と戯れたことがある人ならば、using namespace stdについて理解しているだろう。理解した上で、それでもなおusing namespace stdしたいとなれば、そこには確固たる理由があるはずだ。
そんなこと考えずに軽々しくusing namespace stdしようとしている人や、あるいはC++初学者でサンプルコードを真似てusing namespace stdと書こうとしている人は、using namespace stdの効果と副作用について学んだ後に、再度using namespace stdするか否かを検討すること。
スコープを限定する
using namespace stdのようなusing指令(usingディレクティブ)は、名前空間や関数の中に記述することができる。この時、名前空間の中に記述したならその名前空間のブロックの中でのみ、関数内なら当該関数の中でのみ、using指令が有効となる。
旧来のファイルスコープの考え方も有効だ。コンパクトなソースファイルならば、必要なヘッダファイルをひとしきりインクルードした後にusing namespace stdしても大丈夫なケースもありうるだろう。
using namespace stdの効果を無分別に広範囲にばら撒くのは危険だが、スコープを限定することで制御可能な範疇に留めることができるかもしれない。
なお、ヘッダファイル中のグローバルなスコープにusing namespace stdと書く奴は、5分の1の確立でイスの脚に右足の小指をぶつける呪いにかかると風の噂に聞いたことがある。
対象とする識別子を限定する
using指令ではなくusing宣言を用いて、ターゲットとなる識別子を限定するのも悪くないだろう。
例えば、ターゲットとしてstd::coutとstd::endlだけで十分ならば、using namespace std;よりもusing std::cout; using std::endl;の方がマシだろう(C++17以降ならばusing std::cout, std::endl;と書くことも可能だ)。
using宣言にもスコープの概念が適用されるので、必要最小限の範囲でのみusing宣言が適用されるようにするとよい。
なお、ヘッダファイル中のグローバルなスコープにusing宣言を書く奴は、週に1回ほど自宅から50m離れたころに玄関を施錠したか思い出せなくて猛烈に気になる呪いにかかると、その筋の専門家が話しているらしい。
using namespace stdの副作用についての私見
using namespace stdの意味と効果については他所に解説を譲るとして、using namespace stdの悪影響は、以下の2点の合わせ技から生じているように見える。
std名前空間の中に、標準ライブラリの「結構な分量の識別子」が、割とフラットに存在する。- 標準ライブラリの識別子に「比較的一般的なワード」が多く含まれている。
モダンなプログラミング言語の標準ライブラリとは異なり、C++の標準ライブラリの機能は比較的フラットな感じに公開されていることが多い。例えば<algorithm>ヘッダで公開されているテンプレート関数の多くはstd名前空間の直下に定義されている。
そのため、using namespace stdすることで、予想外に多い識別子と干渉しうる状態になってしまう。
(後発のプログラミング言語の流儀に従うならば、例えばstd::algorithmという名前空間を定義して、その直下にテンプレート関数を定義する、みたいなアプローチがとられるように思うのだが、どうだろうか?)
その上で、標準ライブラリで用いられている識別子の多くは、比較的一般的なワードだ。一般的である分だけ、開発者が使おうと思ったワードと被る可能性が高くなる。
合わせ技の(1)と(2)のどちらか一方だけでも現状と異なっていたならば、using namespace stdの悪影響はもう少し小さくなっていたのではないだろうか?
まあC++は意外と歴史がある上に、より古いC言語の諸々(仕様もライブラリも資産も!)を引き継いでいる訳で、using namespace stdの悪影響については「結果としてそうなっちゃった……」という部類の代物だろうと思っている。
この辺の状況はC++20以降のモジュールの導入によって徐々に変化するだろう、と期待している。同時に、C++23で導入されたのがstdモジュールとstd.compatモジュールである点を鑑みるに、標準ライブラリ全体のモジュールの再編にはまだまだ時間がかかりそうだと感じている(何しろ再編が大変だから「最小限のモジュール化」としてstdモジュールが導入された訳なので)。