2012-02-06 12 views
7

私はこのようなコードスニペットを持って、++ 2010STLセットVCでコンパイルする交差点と出力

 std::set<int> s1; 
     std::set<int> s2; 
     std::set<int> res_set; 
     std::set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(), res_set.begin()); 

。しかし、私はビルドエラーを取得:

c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm(4494): error C3892: 'std::_Tree_const_iterator<_Mytree>::operator *' : you cannot assign to a variable that is const 
1>   with 
1>   [ 
1>    _Mytree=std::_Tree_val<std::_Tset_traits<int,std::less<int>,std::allocator<int>,false>> 
1>   ] 
1>   c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm(4522) : see reference to function template instantiation '_OutIt std::_Set_intersection<_InIt1,_InIt2,_OutIt>(_InIt1,_InIt1,_InIt2,_InIt2,_OutIt)' being compiled 
1>   with 
1>   [ 
1>    _OutIt=std::_Tree_const_iterator<std::_Tree_val<std::_Tset_traits<int,std::less<int>,std::allocator<int>,false>>>, 
1>    _InIt1=std::_Tree_unchecked_const_iterator<std::_Tree_val<std::_Tset_traits<int,std::less<int>,std::allocator<int>,false>>>, 
1>    _InIt2=std::_Tree_unchecked_const_iterator<std::_Tree_val<std::_Tset_traits<int,std::less<int>,std::allocator<int>,false>>> 
1>   ] 
1>   c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm(4549) : see reference to function template instantiation '_OutIt std::_Set_intersection1<std::_Tree_unchecked_const_iterator<_Mytree>,std::_Tree_unchecked_const_iterator<_Mytree>,_OutIt>(_InIt1,_InIt1,_InIt2,_InIt2,_OutIt,std::tr1::true_type)' being compiled 
1>   with 
1>   [ 
1>    _OutIt=std::_Tree_const_iterator<std::_Tree_val<std::_Tset_traits<int,std::less<int>,std::allocator<int>,false>>>, 
1>    _Mytree=std::_Tree_val<std::_Tset_traits<int,std::less<int>,std::allocator<int>,false>>, 
1>    _InIt1=std::_Tree_unchecked_const_iterator<std::_Tree_val<std::_Tset_traits<int,std::less<int>,std::allocator<int>,false>>>, 
1>    _InIt2=std::_Tree_unchecked_const_iterator<std::_Tree_val<std::_Tset_traits<int,std::less<int>,std::allocator<int>,false>>> 
1>   ] 
1>   c:\p4r\pkrcode\depot\dev\stats\poker\protype\statserver\achievementmanager.cpp(175) : see reference to function template instantiation '_OutIt std::set_intersection<std::_Tree_const_iterator<_Mytree>,std::_Tree_const_iterator<_Mytree>,std::_Tree_const_iterator<_Mytree>>(_InIt1,_InIt1,_InIt2,_InIt2,_OutIt)' being compiled 
1>   with 
1>   [ 
1>    _OutIt=std::_Tree_const_iterator<std::_Tree_val<std::_Tset_traits<int,std::less<int>,std::allocator<int>,false>>>, 
1>    _Mytree=std::_Tree_val<std::_Tset_traits<int,std::less<int>,std::allocator<int>,false>>, 
1>    _InIt1=std::_Tree_const_iterator<std::_Tree_val<std::_Tset_traits<int,std::less<int>,std::allocator<int>,false>>>, 
1>    _InIt2=std::_Tree_const_iterator<std::_Tree_val<std::_Tset_traits<int,std::less<int>,std::allocator<int>,false>>> 
1>   ] 

それのために、私は明示的なテンプレートパラメータ宣言製:

std::set_intersection<std::set<int>::const_iterator, std::set<int>::const_iterator, std::set<int>::iterator>(
    s1.begin(), s1.end(), s2.begin(), s2.end(), res_set.begin() 
); 

をしかし、私は同じエラーを持っています。ここでの問題は、2番目のケースでは、const_iteratorを渡すと、パラメータ型が一致しないため、const_iteratorとiteratorの間の変換エラーで失敗するはずです。私はここで何が欠けていますか?

答えて

8

std::set_intersectionに出力引数が可変 value_typeにする必要があります。 std::setの反復子は、 に属していた要素の値を変更すると、セットを変更する可能性があるため、突然変異をサポートしません。 std::set_iteratorのグループ内の関数は、並べ替えられたシーケンス(例えば、ソート順)を処理するために と設計されています。 std::vector。あなたのケースでは

は、あなたのstd::set、必要に応じて(そしておそらくそれらの挿入の顔にソートを保つためにstd::lower_boundと 挿入を使用して)、それらを仕分けstd::vector、 との交換、または std::insert_iterator(res_set, res_set.end())を使用することができます。

+0

記録のために、私は2つのセットの交点が些細な形でなければならないと考えていました。私は、デフォルトでセットを扱う交差法はないことに少し驚いています。私は何かを逃したのか、それはSTLの欠点です。 – progician

+0

Jamesは、セットされた関数は、ソートされたベクトルと同じように、セットで使用するように設計されています。セットをベクトルに変更するだけでは何も解決されません。間違っているのは、書き込めない最後のパラメータだけです。挿入イテレータは、セット*または* aベクトルのそれを修正します。 –

+0

'std :: set'は実際には数学的な意味での集合ではありません。少なくとも、それは部分的にしかありません。一般に、コンピュータサイエンスでは、セットは、重複がなく、多かれ少なかれ迅速なルックアップを持つ単純な順序付けされていないコレクションです。 'std :: set'は順序を追加しますが、そうでなければこの定義を満たします。 (パスカルは数学的な意味でのセットを持っていましたが、小さな整数に限られていました。'std :: bitset'にもっと似ています。) –

11
std::set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(), res_set.begin()); 

(私はset_intersectionの「サーター」の形を知っているが、私はここで間違って何をしますか学びたい)最後のパラメータは、出力イテレータでなければなりません。あなたの場合、それは不変ではありません(bc。std::setには不変要素があります)。あなたは代わりにinsert_iteratorを使用する必要があります。

std::set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(), std::inserter(res_set, res_set.end())); 
8

res_set.begin()は、2つの理由のためset_intersectionの出力引数として使用することはできません。

  • セットが空であり、これは、既存の要素を上書きしようとしますセット
  • セットの要素を変更することはできません。

代わりに、セットに新しい要素を挿入するinsert_iteratorを、欲しい:

std::set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(), 
         std::inserter(res_set, res_set.end())) 
関連する問題