インライン フレンド関数の範囲を明らかにする
C の複雑さの迷宮では、インライン フレンド関数の領域を理解するのは困難な作業になる場合があります。この謎を解明するために、重要な質問を詳しく調べてみましょう: このような関数の実際のスコープは何ですか?
名前空間スコープでのフレンド関数宣言
インライン フレンド関数の場合はクラス内で宣言されていますが、驚くべきことに、クラス スコープ内に自動的には常駐しません。代わりに、それを囲む最も近い名前空間スコープ内に存在を確立します。ただし、この存在は、非修飾および修飾されたルックアップの監視の目によって隠蔽され、視界から隠蔽されたままです。標準のルックアップではインラインのフレンド関数はわかりにくいため、引数依存として知られる希望の光が存在します。ルックアップ (ADL)。この秘密のアプローチにより、オブジェクトまたは含まれるクラスの式のコンテキスト内で修飾されていない関数呼び出しが行われた場合に、コンパイラが隠し関数を明らかにすることができます。
スコープのあいまいさのコードの現れ
スコープの複雑さを説明するために、次のコードを考えてみましょう。スニペット:
baz() 関数を直接呼び出そうとするたびに失敗し、非修飾および修飾されたルックアップによる直接アクセスを妨げる目に見えない障壁が浮き彫りになります。ただし、call_friend() メンバー関数では、ADL の慈悲深い力のおかげで、baz() はスコープの制約に妨げられずに輝きます。
Standard Seal of Authority
namespace foo { struct bar { friend void baz() {} void call_friend(); }; } int main() { foo::baz(); // can't access through enclosing scope of the class foo::bar::baz(); // can't access through class scope } namespace foo { void bar::call_friend() { baz(); // can't access through member function } }
この不可解な動作の最終的な説明は ISO/IEC 14882:2011 にあります。 standard:
"名前空間で最初に宣言された名前はすべて、その名前空間のメンバーです。非ローカル クラスのフレンド宣言が最初にクラスまたは関数を宣言した場合、そのフレンド クラスまたは関数は最も内側のクラスのメンバーになります。囲む名前空間。その名前空間スコープ内 (クラスの前または後のいずれか) で一致する宣言が提供されるまで、友達の名前は非修飾検索 (3.4.1) または修飾付き検索 (3.4.3) では見つかりません。フレンド関数が呼び出された場合、関数の引数の型に関連付けられた名前空間とクラスからの関数を考慮した名前検索によってその名前が見つかる可能性があります (3.4.2)。"これこの抜粋は、明示的な名前空間修飾なしで宣言されたフレンド関数の一時的な性質を強調しています。彼らは、それを囲む名前空間のエーテル領域に生息しており、ADL の神秘的な儀式を通じて召喚される場合を除いて、標準的な視線にはとらえどころのないままです。
以上がC のインライン フレンド関数のスコープは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。