[解決済み] Argument-Dependent Lookup」(別名ADL、「Koenig Lookup」)とは何ですか?
質問
引数依存型ルックアップとは何か、何か良い説明はありますか?また、多くの人がケーニッヒ・ルックアップと呼んでいます。
できれば知りたいです。
- なぜ良いことなのでしょうか?
- なぜ悪いのですか?
- どのように機能するのですか?
解決方法は?
ケーニッヒルックアップ または 引数依存型ルックアップ は、C++で非修飾名がコンパイラによってどのようにルックアップされるかを説明しています。
C++11標準§3.4.2/1には、以下のように記載されています。
関数呼び出しの後置表現 (5.2.2) が unqualified-id の場合、通常の非限定検索 (3.4.1) では考慮されない他の名前空間が検索され、その名前空間で、他の方法では見えない名前空間スコープの友人関数宣言 (11.3) が見つかる場合があります。検索に対するこれらの変更は,引数の型に依存します(そして,テンプレートテンプレート引数の場合は,テンプレートテンプレートの名前空間に依存します)。 引数)。
もっと簡単に言うと、ニコライ・ヨスッティは次のように述べています。 1 :
1つ以上の引数型が関数の名前空間で定義されている場合、関数の名前空間を修飾する必要はありません。
簡単なコード例です。
namespace MyNamespace
{
class MyClass {};
void doSomething(MyClass) {}
}
MyNamespace::MyClass obj; // global object
int main()
{
doSomething(obj); // Works Fine - MyNamespace::doSomething() is called.
}
上記の例では
using
-宣言と
using
-ディレクティブを使用しても、コンパイラは未修飾の名前を正しく認識します。
doSomething()
で宣言された関数として、名前空間
MyNamespace
を適用することで
ケーニッヒルックアップ
.
どのように機能するのですか?
このアルゴリズムは、ローカルスコープだけでなく、引数の型を含む名前空間も見るようにコンパイラに指示する。したがって、上記のコードでは、コンパイラはオブジェクトの
obj
関数の引数である
doSomething()
に属し、名前空間
MyNamespace
. そのため、その名前空間を検索して
doSomething()
.
ケーニッヒルックアップのメリットは何ですか?
上の簡単なコード例が示すように、ケーニッヒ参照はプログラマーに便利さと使いやすさを提供します。ケーニッヒ検索がなければ、プログラマーは完全修飾名を何度も指定したり、代わりに多数の
using
-を宣言しています。
ケーニッヒルックアップの批判はなぜ?
ケーニッヒ・ルックアップに過度に依存すると、意味上の問題が発生し、プログラマが不意を突かれることがある。
の例を考えてみましょう。
std::swap
これは、2つの値を交換する標準的なライブラリアルゴリズムです。ケーニッヒ検索では、このアルゴリズムを使用する際に注意しなければならないことがあります。
std::swap(obj1,obj2);
と同じ挙動を示さない場合があります。
using std::swap;
swap(obj1, obj2);
ADLでは、どのバージョンの
swap
関数が呼び出されるかどうかは、渡された引数の名前空間によって決まります。
もし、名前空間
A
で、もし
A::obj1
,
A::obj2
および
A::swap()
が存在する場合、2番目の例では、結果として
A::swap()
これは、ユーザーが望んでいたものとは異なるかもしれません。
さらに、何らかの理由で
A::swap(A::MyClass&, A::MyClass&)
と
std::swap(A::MyClass&, A::MyClass&)
が定義されている場合、最初の例では
std::swap(A::MyClass&, A::MyClass&)
が、2番目のものはコンパイルされません。
swap(obj1, obj2)
は曖昧になる。
トリビアです。
なぜ「ケーニッヒ・ルックアップ」と呼ばれるのですか?
元AT&Tやベル研究所の研究者やプログラマーが考案したものだからです。 アンドリュー・ケーニッヒ .
さらに読む
-
Standard C++03/11 [basic.lookup.argdep]: 3.4.2 引数依存の名前ルックアップ。
<サブ ** 1 ** ケーニッヒ・ルックアップの定義は、Josuttis氏の著書「The C++ Standard Library」で定義されている通りです。A Tutorial and Reference*に定義されています。
関連
-
[解決済み】非静的メンバ関数への参照を呼び出す必要がある
-
[解決済み】クラステンプレートの引数リストがない
-
[解決済み】ファイルから整数を読み込んで配列に格納する C++ 【クローズド
-
[解決済み] ルール・オブ・スリーとは?
-
[解決済み] コピーアンドスワップ慣用句とは?
-
[解決済み] C++11では、標準化されたメモリモデルが導入されました。その意味するところは?そして、C++プログラミングにどのような影響を与えるのでしょうか?
-
[解決済み] スマートポインターとは何ですか?
-
[解決済み] ムーブセマンティクスとは何ですか?
-
[解決済み】C/C++の"-->"演算子とは何ですか?
-
[解決済み】C++11のラムダ式って何?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】 unsigned int vs. size_t
-
[解決済み】C++エラー。アーキテクチャ x86_64 に対して未定義のシンボル
-
[解決済み】「corrupted size vs. prev_size」glibc エラーを理解する。
-
[解決済み】fpermissiveフラグは何をするのですか?
-
[解決済み】エラー:strcpyがこのスコープで宣言されていない
-
[解決済み】C++の余分な資格エラー
-
[解決済み】CMakeエラー at CMakeLists.txt:30 (project)。CMAKE_C_COMPILER が見つかりませんでした。
-
[解決済み] 解決済み] `pthread_create' への未定義の参照 [重複] [重複
-
[解決済み】std::cin.getline( ) vs. std::cin
-
[解決済み】デバッグアサーションに失敗しました