このコードは再度コンパイルエラーになります。9行目で呼ばれているfuncのシンボルをグローバルネームスペースから探そうとするのですが、実際に定義されているfuncはns1ネームスペースの中にある為、通常の名前検索ではヒットしない為です。ネームスペースを指定した上で呼び出す必要があります。0;}まったく何を読まされているんだという感じでしょうが、ここまではウォーミングアップです。具体的な実装コードを見てみましょう。ns1に色情報を持つ構造体と、内容を出力する関数を定義しました。printにns1を付けずに呼ぶ。printにns1を付けずに呼ぶ。0;}このmain関数をよく見て下さい。Colorの型にはns1::という指定が付いていますが、printはネームスペースの指定を付けずに呼び出しています。このコードはコンパイルエラーになりません。c++様はある型のオブジェクトが関数呼出の際に実引数として用いられると、関連するネームスペースからも、その関数が探索されるという仕様だからです。今回の場合は、printの引数で渡されているcの型がns1::Colorで、ns1ネームスペースに関係があるため、printという関数のシンボル検索グローバルネームスペースからだけではなく、関係があるns1からも検索するという挙動になります。これが「実引数依存の名前検索(ADL)」の挙動です。「関連するネームスペース」とは何でしょうか。引数がクラスのメンバだった場合そのクラス自身および基底クラス、そしてそのクラスを囲むネームスペースです。std::vector::iteratorはクラスのメンバですので、vectorとstdが関連するネームスペースになりますね。引数がネームスペースのメンバだった場合あるネームスペースの中で定義されているだけのクラスの場合、関連するネームスペースはそのクラスを囲むネームスペースです。そのクラスが継承していれば継承元のクラスに対して、同様の条件に基いて関連するネームスペースが決定します。前述のとおりADLは人間の目では一見しただけではわからないネームスペースからもシンボルを探そうとします。その結果、本来意図しない関数が呼び出される危険性もあります。大丈夫、予期せぬADLの防止策もちゃんとあります。Firewallまた、この辺りの注意点について詳しく解説しているサイトも多いので色々参照してみるとよいでしょう。注意]なぜ存在するのか複雑性を増すだけに思えるこのADLという仕組みがなぜ必要なのか。それは演算子をネームスペースの修飾無しで呼べるようにするためです。b);と、何とも味わい深い呼び出し方をするしかなくなってしまいます。これはストリーム演算子含むあらゆる演算子に言えることです。登場する<<演算子も本来stdのネームスペースの中にあるので、ADLが無いと直感的に呼び出せないのです。std::<<の呼び出し}またSTLのswapのように(と言っても他に良い例を知らないですが)あえてADLの挙動を利用して汎用的な処理ができるようにしているコードもあります。STLの中で呼ばれる修飾無しのswapはユーザー定義のものがADLで見つかればそれを呼ぶし無ければstd::swapが呼ばれるという実装になっています。