引数依存ルックアップ (ADL) が発明されたのはなぜですか? cout << stuff
の代わりに書けるようにするためstd::operator<<(cout, stuff)
ですか?その場合、ADL がすべての関数ではなく演算子に限定されなかったのはなぜですか?
C++ に組み込み型とユーザー定義型の両方のジェネリック出力を行う別の方法があった場合、ADL の導入を防ぐことができたprintf
でしょうか。
引数依存ルックアップ (ADL) が発明されたのはなぜですか? cout << stuff
の代わりに書けるようにするためstd::operator<<(cout, stuff)
ですか?その場合、ADL がすべての関数ではなく演算子に限定されなかったのはなぜですか?
C++ に組み込み型とユーザー定義型の両方のジェネリック出力を行う別の方法があった場合、ADL の導入を防ぐことができたprintf
でしょうか。
ADLは、インターフェイスの原則を可能にするために考案されました。
インターフェイスの原則
クラスXの場合、無料の関数を含むすべての関数は、
Xのインターフェイスの一部を形成するため、論理的にはXの一部です。
このトピックについては、ハーブサッターの優れた今週の達人をチェックしてください。
その場合、ADLがすべての関数ではなく演算子に制限されなかったのはなぜですか?
なぜ人為的に制限するのですか?ADLの実装は難しいかもしれませんが(C ++のオーバーロードルールと組み合わせると)1、非常に便利な手法です。1つには、関数でも機能するため、名前空間全体をインポートしなくても、他の名前空間を使用するのがはるかに簡単になります。
適切な例として、SeqAnライブラリ:
using seqan::String;
String<Char> url = "http://www.seqan.de/";
std::cout << "The URL " << url << " has length " << length(url) << std::endl;
seqan::length
フルネームを修飾せずに関数を使用したことに注意してください。ADLはとにかくそれを見つけます。SeqAnライブラリは、このような名前空間スコープ関数を過度に使用し、すべての使用法の前に名前空間名を付けるのは実用的ではありません。同様に、名前空間をインポートすることはお勧めできません。
もちろん、Boostのほとんどなど、他の多くのライブラリにも同じことが言えます。
1そして、これは委員会によってすぐには実現されなかったと思います。
なぜそれを演算子に限定しないのですか?
単純な汎用アルゴリズムを見てみましょう。
template <typename FwdIt, typename T>
FwdIt remove(FwdIt first, FwdIt last, T const& value)
{
using std::swap;
FwdIt result = first;
for ( ; first != last; ++first)
if (!(*first == value)) swap(*result++, *first);
return result;
}
カスタム タイプと独自のバージョンの でどのように機能し swap
ますか? ADLに感謝します。
これは、ダニエルが述べたように、 Sutter がInterface Principleと呼んでいるものです。
関数の多型を可能にするために発明されました。関数は動詞(「print」など)であり、意味は1つだけであるという考え方です。それでも、動詞の適用対象(int、float、std :: stringなど)に応じて、実装が異なる場合があります。
したがって、概念には1つの単語が必要ですが、適用対象に応じていくつかの実装が必要です。
適用されるのは引数です。そのため、いくつかの異なるタイプの引数で同じ単語を使用する方法が必要でした。必要に応じて、argument-type-relativeの実装が必要です。
printInt()、printString()、printFloat()関数を使用して複雑な連結を記述してみると、明らかな冗長性がわかります。
もう1つの理由は、指定された引数タイプで実装が使用可能かどうかを確認できることです。利用可能な実装がない場合(ジェネリックでもない-テンプレートを使用)、コンパイラはできるだけ早くあなたを停止し、指定された引数の動詞の実装がないことを通知します。
はい、主にオペレーター向けに発明されました。ただし、非メンバー関数をクラスのインターフェイスに組み込むこともできます。そして、これは私がとても気に入っている非常に強力なものです。そして、これはもはやオペレーターに限定されません。たとえば、クラスのcross_product
関数を定義したい場合がありますvector
-あなたは私が何を意味するか知っています:)