C++ setのイテレータ経由でinsertできない

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

C++ setのイテレータ経由でinsertできない

#1

投稿記事 by beatle » 13年前

以下のコードで、なぜit経由だとinsertできず、s2経由だとinsertできるのか分かりません。
なぜコンパイルに通らないか分かる方、教えてください。

it->insertの行を有効にしてコンパイルしようとすると以下の様なコンパイルエラーとなります(clang++, g++ともにエラーになります)。
► スポイラーを表示

コード:

#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できない

#2

投稿記事 by しひ » 13年前

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;

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: C++ setのイテレータ経由でinsertできない

#3

投稿記事 by beatle » 13年前

返信ありがとうございます。
確かに、イテレータ経由で要素を勝手にいじられると、setの中での順番が変わらないといけないときであっても順番が変わらないまま、整合性がなくなってしまいますね。
setの中身を弄るときは erase してから insert するのが基本だよとTwitterで教えてもらいました。

どうやら iterator と const_iterator が同じ宣言になってしまっているのはバグのようですね。
103. set::iterator is required to be modifiable, but this allows modification of keys

kariya_mitsuru

Re: C++ setのイテレータ経由でinsertできない

#4

投稿記事 by kariya_mitsuru » 13年前

beatle さんが書きました:どうやら iterator と const_iterator が同じ宣言になってしまっているのはバグのようですね。
103. set::iterator is required to be modifiable, but this allows modification of keys
少なくとも C+11 では、iterator と const_iterator は同じ型でも構わないことになっています。
(リンク先にも記載がありますよ)

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: C++ setのイテレータ経由でinsertできない

#5

投稿記事 by beatle » 13年前

ありがとうございます。
確かに C++11 にて associative containers の要件が修正されていますね。

閉鎖

“C言語何でも質問掲示板” へ戻る