ページ 1 / 1
C++ setのイテレータ経由でinsertできない
Posted: 2012年8月04日(土) 14:45
by beatle
以下のコードで、なぜit経由だとinsertできず、s2経由だとinsertできるのか分かりません。
なぜコンパイルに通らないか分かる方、教えてください。
it->insertの行を有効にしてコンパイルしようとすると以下の様なコンパイルエラーとなります(clang++, g++ともにエラーになります)。
► スポイラーを表示
コード:
main.cpp:10:9: error: no matching member function for call to 'insert'
it->insert(s2.begin(), s2.end()); // ERROR
~~~~^~~~~~
/usr/include/c++/4.2.1/bits/stl_set.h:344:9: note: candidate function [with _InputIterator =
std::_Rb_tree_const_iterator<int>] not viable: no known conversion from 'pointer' (aka 'const std::set<int,
std::less<int>, std::allocator<int>> *') to 'std::set<int, std::less<int>, std::allocator<int>>' for object
argument;
insert(_InputIterator __first, _InputIterator __last)
^
/usr/include/c++/4.2.1/bits/stl_set.h:331:7: note: candidate function not viable: no known conversion from 'pointer'
(aka 'const std::set<int, std::less<int>, std::allocator<int>> *') to 'std::set<int, std::less<int>,
std::allocator<int>>' for object argument;
insert(iterator __position, const value_type& __x)
^
/usr/include/c++/4.2.1/bits/stl_set.h:304:7: note: candidate function not viable: requires 1 argument, but 2 were
provided
insert(const value_type& __x)
^
1 error generated.
コード:
#include <set>
using namespace std;
void f()
{
set<set<int>> s1;
set<int> s2;
set<set<int>>::iterator it;
//it->insert(s2.begin(), s2.end()); // ERROR
s2.insert(s2.begin(), s2.end()); // OK
}
Re: C++ setのイテレータ経由でinsertできない
Posted: 2012年8月04日(土) 17:41
by しひ
std::set::iteratorがconst_iteratorのエイリアスになっているからではないでしょうか。
恐らくsetの整合性を保つためではないかと思いますが、詳しいことは知りません。
コード:
// g++ 4.7.0
// bits/stl_set.h
// DR 103. set::iterator is required to be modifiable,
// but this allows modification of keys.
typedef typename _Rep_type::const_iterator iterator;
typedef typename _Rep_type::const_iterator const_iterator;
Re: C++ setのイテレータ経由でinsertできない
Posted: 2012年8月04日(土) 23:05
by beatle
返信ありがとうございます。
確かに、イテレータ経由で要素を勝手にいじられると、setの中での順番が変わらないといけないときであっても順番が変わらないまま、整合性がなくなってしまいますね。
setの中身を弄るときは erase してから insert するのが基本だよとTwitterで教えてもらいました。
どうやら iterator と const_iterator が同じ宣言になってしまっているのはバグのようですね。
103. set::iterator is required to be modifiable, but this allows modification of keys
Re: C++ setのイテレータ経由でinsertできない
Posted: 2012年9月03日(月) 15:09
by kariya_mitsuru
少なくとも C+11 では、iterator と const_iterator は同じ型でも構わないことになっています。
(リンク先にも記載がありますよ)
Re: C++ setのイテレータ経由でinsertできない
Posted: 2012年9月03日(月) 20:06
by beatle
ありがとうございます。
確かに C++11 にて associative containers の要件が修正されていますね。