7

このようなコード スニペットを VC++ 2010 でコンパイルします。

        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 の間の変換エラーで失敗することです。ここで何が欠けていますか?(set_intersectionの「挿入」形式については知っていますが、ここで何が間違っているのかを知りたいです)

4

3 に答える 3

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

最後のパラメーターは、出力反復子でなければなりません。あなたの場合、それは不変ではありません(bc.std::setには不変の要素があります)。代わりに insert_iterator を使用する必要があります。

    std::set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(), std::inserter(res_set, res_set.end()));
于 2012-02-06T13:46:26.103 に答える
8

a への出力引数は、変更可能な でstd::set_intersectionなければなりません value_typestd::set要素の値を変更すると、その要素がセット内のどこに属しているかが変わる可能性があるため、のイテレータは決してミューテーションをサポートしません。with グループの関数は、std::set_iteratorソートされたシーケンスで動作するように設計されていstd::vectorます。

あなたの場合、必要に応じてそれらstd::setstd::vector並べ替えて(そしてstd::lower_bound、挿入に直面してそれらを並べ替えるためにおよび挿入を使用して)、またはを使用することができます std::insert_iterator( res_set, res_set.end() )

于 2012-02-06T13:52:23.807 に答える
8

res_set.begin()set_intersection次の 2 つの理由により、 の出力引数として使用できません。

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

insert_iterator代わりに、新しい要素をセットに挿入するために, が必要です。

std::set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(), 
                      std::inserter(res_set, res_set.end()))
于 2012-02-06T13:48:32.657 に答える