1

Visual Studio 2010 のコードを考えると:

void Foo::Bar() const
{
    map_t::const_iterator iter(my_map_.find(key));

    if(my_map_.end() != iter)
        DoStuff(iter->second);
}

Do stuff は、mapped_type を値で受け取ります。マップされた型は、コピー可能、移動可能、割り当て可能な型です。

2 番目にアクセスしようとすると、キーと値のペアをコピーできないというエラー メッセージが表示されます。私が自分の行に書いても:

iter->second;
(*iter).second;

DoStuffとは何の関係もないことを確認するために...

operator-> または operator* を返す前に、イテレータがキーと値のペアのコピーを作成していると思います。

マップされた型のコピーを取得するにはどうすればよいですか?

編集:

マップ自体は、大まかに次のように、バリアントをブーストするための unsigned short です。

typedef struct{} empty_t;
typedef boost::variant<empty_t, double, long, some POD types> variant_t;
typedef std::map<unsigned short, variant_t> map_t;

そして、クラスのプライベート メンバーとして:

map_t my_map_;

明確にするために、問題は DoStuff に渡すことではありません。その行を削除して、単純にイテレータを逆参照して 2 番目にアクセスすると、コンパイラ エラーが発生します。

if(my_map_.end() != iter)
        iter->second; //Doesn't do anything, but illustrates the error.
4

2 に答える 2

0

編集 ブーストの結果として与えられた質問の更新が無効な回答::バリアント (残りの問題情報が利用可能になると、最終的な回答で更新されます)。

DoStuff が変数を参照または値で取得し、const_iterator から変数を直接渡す場合、DoStuff には const 参照または const 値のオーバーロードされた関数呼び出しが必要です (オブジェクト型に既定の const から非 const への変換が使用可能な場合を除く)。 . そうしないと、const 要素を非 const として扱うため、コンパイラが文句を言います。

もう 1 つのオプションは、 iter->second を別の変数に (要素の型に応じてコンストラクターまたは代入を介して) 割り当て、それを DoStuff に渡すことですが、関数の const オーバーロード バージョンを定義することをお勧めします。

于 2012-07-26T20:53:17.863 に答える
0

私はそれを考え出した。

WAYYYYY はこのコードから離れており、いくつかの抽象化が深く、マップへのイテレータが std::partition に渡されていました! マップを分割することはできないようです。

マップの内容をローカル ベクトルにコピーし、そこから処理を続行したところ、すべてのエラー メッセージがクリアされました。

なぜコンパイラがこれほどまでに混乱していたのか、私にはわかりません。問題のコードは、まったく関係のない場所にありました。しかし、それは問題ではありません。

于 2012-08-07T21:06:49.097 に答える