このコードは再度コンパイルエラーになります。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が呼ばれるという実装になっています。teppyCPUには得意なデータ型というものがあります。あるCPUでは4byteの数値計算が最も高効率に少ないクロック数で処理でき、また別のCPUでは8byteの数値計算が最も高効率に処理できる、といった具合です。(あと8bit演算は常に高速でした)その頃はintも往々にして4byteだったので、数値をやりとりする場合の引数、または戻り値の指定は単にintにしておけば良かったのです。arg;}今でもそのころの名残で、慣例的に引数、戻り値をintで受ける書き方をしている人も多いのではないでしょうか。今やどこを見ても64bitCPUで溢れています。関わらず、多くの環境でintは4byteのままです。今の時代で引数に盲目的にintを指定することは、環境の変化に対応しきれていない可能性があります。幸いにも、どの環境でもなるべく高効率になる数値型を標準が用意してくれています。64bitの精度を保証した符号無し整数型fastの後ろの数値が最低限保証するbit精度です。uint_fast8_tは「最低でも8bitの精度が保証された中で最速のデータ幅」を持つ符号無し整数を表します。0~100までの数値を引数で受け取って10倍にして返すという、(なんの使い道もない)関数を定義してみましょう。10;}精度が保証されているだけで8bit整数(std::uint8_t)と同じbit幅とは限らない点に注意して下さい。std::uint_fast8_tのデータ幅は16bitかもしれませんし、64bitかもしれません。参考までに手元の環境における各型のサイズを示します。teppy数値型の別名定義を用意しているプロジェクトは多いです。以下各型それぞれに続く符号付か否か、あとは型の持つbit数などを踏まえたエイリアスを用意することでタイピング数の削減と統一的な名前規則でコードを分かりやすくしようという意図が感じられます。一定規模以上のプロジェクトになると、ほぼ必ず上記のような型の再定義ファイルがあるように感じます。既視感のある人も多いのではないでしょうか。上記の例は非常にポータビリティに欠ける為、行うべきではありません。ユーザーが「intの別名はs32」と定義したところで、実際にs32のサイズが32bitになる保証はどこにもありません。サイズが保証された数値型を標準が用意してくれているので、そちらを使うようにしましょう。64bitまでのビットサイズが保証された符号付/無整数型どんな環境でもstd::int8_tは8bit符号付き整数を表すことが保証されています。アドレス型のサイズとintのサイズが違う環境も多いので、アドレスを数値として計算する場合は気をつけましょう。64bitCPUの場合、アドレスの値の範囲は64bitですがintのサイズは32bitというケースも多いです。reinterplet_cast<int>(&obj_b);obj_aのアドレスとobj_bのアドレスの差分を計算するコードですが、例えばポインタが64bitなのにintは32bitだった場合、サイズオーバーのため正しい計算結果が得られない可能性が高いです。ポインタ(アドレス)を数値として計算する場合は、ちゃんとアドレスと同じ値の幅を持つことが保証されている数値型std::intptr_t、もしくはstd::uintptr_tを使いましょう。reinterplet_cast<std::intptr_t>(&obj_b);あなたが一生懸命作ったスマートフォン向けのゲームを3DSに移植したら全然動かなくなっちゃった!とならないためにも日頃からポータビリティを意識したコードを書くようにしましょう。