4

I recently got introduced the design of generic programming libraries like STL, boost::graph, boost PropertyMaps http://www.boost.org/doc/libs/1_54_0/libs/property_map/doc/property_map.html

What is the rationale behind using free functions like get(PropertyMap, key) over member functions like PropertyMap.get(key)?

I understand that the most generic form of these functions are defined in the "boost" namespace. Suppose I define a new PropertyMap in my namespace "project", what is the best place to define it's corresponding "get" function? "boost" or "project"

4

4 に答える 4

6

次の 2 つの理由があります。

  • カプセル化の改善: クラス属性にアクセスする関数の数を最小限に抑えることで、カプセル化を改善します。

  • 拡張性: C++ では、名前空間定義は開いています (追加できます) が、クラス定義は閉じています。したがって、フリー関数は追加できますが、メンバー関数は追加できません。

カプセル化は好みの問題ですが、汎用プログラミングでは拡張性が非常に重要です。必要なメソッドが 1 つ欠けているという理由だけで、サードパーティの型を放棄する必要はありません...もちろん、一部の型 (組み込み型や標準ライブラリ型など) はまったく拡張できません。

于 2013-07-17T17:31:55.690 に答える
3

主な動機は、メンバー以外の非フレンド関数を優先することで、クラスをできるだけ簡潔に保つことができるということです。ここで Herb Sutter の記事を参照してください: http://www.gotw.ca/publications/mill02.htm .

この記事には、質問の他の部分、対応する get 関数を配置する場所への回答も含まれています。これは、Argument Dependent Lookup (ADL) と呼ばれる C++ の機能です。この名前は物議を醸していますが、Herb Sutter はこれを Koenig ルックアップと呼んでいます (以下のコメントを参照)。

Koenig ルックアップによると、クラス型の関数引数を指定した場合、関数名を見つけるためにコンパイラは、ローカル スコープのような通常の場所だけでなく、名前空間 (ここでは NS) を検索する必要があります。引数の型。

次に例を示します。

namespace MyNamespace {
    class MyClass {... };
    void func(MyClass);
}

int main(int aArgc, char* aArgv[]) {
    MyNamespace::MyClass inst;
    func(inst);  // Ok, because Koenig says look in the argument's namespace for func
}

つまり、クラスと同じ名前空間で get 関数を宣言するだけです。

テンプレート パラメーターを明示的に指定する必要がある場合、これはテンプレート化された関数では機能しないことに注意してください。

于 2013-07-17T16:51:24.427 に答える
2

手がかりは質問にあると思います-それはそれらをより一般的にします。フリー関数 likestd::find()は、多数の異なるコンテナーで使用できるため、ジェネリックです。メンバー likestd::map<T>.find()は でのみ機能するstd::mapため、まったくジェネリックではありません。

優れたジェネリック関数を使用すると、コンテナー内に独自のメソッドを作成する必要がなくなります (もちろん、独自のフリー関数を作成する必要もなくなります)。特定の操作を一般的な関数よりもそのコンテナーに固有の方法でより適切に実装できるコンテナーがある場合、メソッドを提供することは理にかなっています (std::mapfind()メソッドは明らかな例です)。

于 2013-07-17T17:29:47.723 に答える