2

std :: set_unionとその親族は、操作対象のセットに対して2組のイテレータを使用します。それが最も柔軟なことであるという点でそれは素晴らしいことです。ただし、通常の使用の80%でよりエレガントな、追加の便利な機能を簡単に作成できたはずです。

例えば:

template<typename ContainerType, typename OutputIterator>
OutputIterator set_union( const ContainerType & container1, 
                const ContainerType & container2, 
                OutputIterator      & result      )
{
    return std::set_union( container1.begin(), container1.end(), 
                           container2.begin(), container2.end(), 
                           result );
}

向きを変えるだろう:

std::set_union( mathStudents.begin(), mathStudents.end(), 
                physicsStudents.begin(), physicsStudents.end(), 
                students.begin() );

の中へ:

std::set_union( mathStudents, physicsStudents, students.begin() );

それで:

  • 私が見つけていない場所に隠れているこのような便利な機能はありますか?

  • そうでない場合、STLから除外される理由を誰かが知ることができますか?

  • ブーストには、おそらくもっとフル機能のセットライブラリがありますか?(見つかりません)

もちろん、いつでもどこかのユーティリティライブラリに実装を配置できますが、すべてのプロジェクトで使用されるように整理するのは困難ですが、不適切に統合されることはありません。

4

5 に答える 5

8

私が見つけていない場所に隠れているこのような便利な機能はありますか?

標準ライブラリにはありません。

そうでない場合、STLから除外される理由を誰かが知ることができますか?

アルゴリズムの一般的な考え方は、コンテナーではなくイテレーターで機能するというものです。コンテナは、変更、変更、および突くことができます。イテレータはできません。したがって、アルゴリズムを実行した後、コンテナ自体は変更されておらず、コンテナの内容のみが変更されている可能性があることがわかります。

ブーストには、おそらくもっとフル機能のセットライブラリがありますか?

Boost.Rangeはこれを行います。確かに、Boost.Rangeはこれ以上のことを行います。アルゴリズムは「コンテナ」を取りません。それらは、STLコンテナがたまたま条件を満たすイテレータ範囲を取ります。また、遅延評価があり、パフォーマンスに優れている可能性があります。

于 2011-07-08T07:56:09.237 に答える
2

イテレータを使用する理由の1つは、もちろん、それがより一般的であり、コンテナではない、またはコンテナの一部である範囲で機能することです。

もう1つの理由は、署名が混同されることです。std :: sortのような多くのアルゴリズムには、すでに複数の署名があります。

sort(Begin, End);
sort(Begin, End, Compare);

2つ目は、標準未満以外で並べ替えるときにカスタム比較を使用するためのものです。

コンテナのセットを追加すると、sortこれらの新しい関数が得られます

sort(Container);
sort(Container, Compare);

これで2つの署名がsort(Begin, End)あり、sort(Container, Compare)どちらも2つのテンプレートパラメーターを取ります。コンパイラーは呼び出しの解決に問題があります。

これを解決するために関数の1つの名前(sort_range、sort_container?)を変更すると、それはもはや便利ではなくなります。

于 2011-07-08T08:37:23.380 に答える
1

@Bo Perssonはあいまいさの問題を指摘しており、それは非常に有効だと思います。

おそらくそれが実際に考慮されることさえできなかった歴史的な理由があると思います。

STLは、標準化プロセスの比較的遅い段階でC++に導入されました。それが受け入れられた直後に、委員会は、C ++ 98に追加するためのこれ以上の新機能を検討することすら反対票を投じました(おそらく同じ会議でも)。ほとんどの人が既存のSTLに頭を悩ませて、個々のイテレータではなく範囲のようなものからどれだけの利便性が得られるかを認識するまでには、考えるには遅すぎました。

委員会がまだ新機能を検討していて、誰かが個別のイテレータの代わりにコンテナを渡すことを許可する提案を書き、あいまいさの可能性に受け入れられるように対処したとしても、提案は拒否されたのではないかと思います。多くの人(特にC指向の人々)は、とにかく標準ライブラリへの巨大な追加としてSTLを見ました。2つではなく1つのパラメーターを渡すことを許可するためだけに、関数/オーバーロード/特殊化を追加(ロット)することは完全に受け入れられないと考える人がかなりいると私は合理的に確信しています。

于 2011-07-08T20:06:42.123 に答える
1

私は同意します。STLは次の理由でイテレータペアの代わりにコンテナを使用する必要があります。

  • より単純なコード
  • 指定されたコンテナに対してアルゴリズムがオーバーロードされる可能性があります。つまり、std::find->より一般的なコードの代わりにmap::findアルゴリズムを使用できます。
  • boost :: rangeで行われるように、サブ範囲はコンテナに簡単にラップできます。
于 2011-07-08T07:59:54.377 に答える
0

反復にbegin要素とend要素を使用すると、コンテナー以外のタイプを入力として使用できます。例えば:

ContainerType students[10];
vector<ContainerType> physicsStudents;
std::set_union(physicsStudents.begin(), physicsStudents.end(), 
               &students[0], &students[10], 
               physicsStudents.begin());

それらは非常に単純な実装であるため、stdライブラリに追加せず、作成者が独自に追加できるようにするのは理にかなっていると思います。特にそれらがテンプレートであることを考えると、コードのlibサイズを増やす可能性があり、std全体に便利な関数を追加すると、コードが肥大化する可能性があります。

于 2011-07-08T07:56:37.127 に答える