2016-04-04 6 views
0

次のコードは、空集合{}で2つの要素集合{2,3}の和集合を形成しようとしています。結果として得られるコンテナ(この場合はリスト)のサイズは2でなければなりません。2つの集合の和集合を作ることは、間違った一貫性のない回答を与えるようです。

しかし、コードを実行すると、2つのうちのどちらに依存するかによって、ユニオンのサイズは0または3になります変数unitedの宣言のために示された場所。これらの結果のどちらも、私が期待したものではなく、明らかに正しいものではありません。

私はここで何が欠けていますか?

#include <list> 
#include <set> 
#include <algorithm> 
#include <iostream> 

using namespace std; 

int main() 
{ 
    //list<int> united; // resulting output is 3 

    int d1[] = {2,3}; 
    set<int> dom1(d1, d1+2); 
    set<int> dom2; 

    list<int> united; // resulting output is 0 

    set_union(dom1.begin(), dom1.end(), dom2.begin(), dom2.end(), united.begin()); 

    cout << united.size(); 

    return 0; 
} 

答えて

3

あなたは第五イテレータがOutputIteratorの要件を満たさなければならないことがわかりますstd::set_unionのドキュメントを見てみてください。あなたがstd::list::beginのドキュメントを見てみた場合

その後、あなたはそれが唯一のInputIteratorのサブタイプであるBidirectionalIteratorある、std::list::iterator (or std::list::const_iterator)を返すことがわかります。

技術的には、非const InputIteratorもOutputIteratorですが、プログラムでは動作しません。それはunitedのノードを反復し、ソース要素を既に存在する要素にコピー・アロケートします。しかし、あなたのケースではunitedが空であるため、反復子は範囲外になり、結果として未定義の動作になります。

新しい要素を挿入するOutputIteratorを簡単に取得するには、std::back_inserterを使用します。

2

一般に、「間違った一貫性のない回答」を得ると、定義されていない動作をしたり、プログラムが診断されずに不正な形式になります。範囲外のバグを探します。

ここでは、出力イテレータは存在しない範囲を参照します。

united.begin()std::back_inserter(united)に置き換えて、必要に応じて要素を作成する必要があります。

これは、一例としてthe cppreference.com std::set_union documentationです。
ドキュメントを読む!

関連する問題