2

マップにペアを挿入しようとすると、不変性の問題が発生します。コンパイラエラーは次のとおりです。

              c:\program files (x86)\microsoft visual studio 11.0\vc\include\xutility(2089) : see reference to function template instantiation 'std::pair<_Ty1,_Ty2> &std::pair<_Ty1,_Ty2>::operator =(const std::pair<_Ty1,_Ty2> &)' being compiled
1>          with
1>          [
1>              _Ty1=const Assets::AssetId,
1>              _Ty2=std::shared_ptr<Assets::Material>
1>          ]
1>          c:\fusionengine\meshgl.cpp(85) : see reference to class template instantiation 'std::pair<_Ty1,_Ty2>' being compiled
1>          with
1>          [
1>              _Ty1=const Assets::AssetId,
1>              _Ty2=std::shared_ptr<Assets::Material>
1>          ]

エラーの原因となっている行は次のとおりです。

m_materials.insert( MaterialsMap::value_type(pMaterial->AssetId(), pMaterial) );

m_materialsマップは次のように宣言されています。

typedef std::map< Assets::AssetId, std::shared_ptr<Material> > MaterialsMap;    
typedef std::pair< Assets::AssetId, std::shared_ptr<Material> > MtlPair;

MaterialsMap  m_materials;

エラー1エラーC2166:l値はconstオブジェクトc:\ program files(x86)\ microsoft visual studio 11.0 \ vc \ include\utilityを指定します114

誰かが私がこの問題を解決する方法を説明できますか?

4

2 に答える 2

3

私はこの問題で髪を引き裂きました。おそらく、1 週間のオンとオフを費やしました。幸いなことに、それはプロジェクトのロードマップにとって重要ではなかったため、続行を妨げることはありませんでした。

この問題はコンパイラに関連したものではありませんでしたが、エラー報告は拡張機能で行うことができましたが、それは常にテンプレート (および STL) コードの問題であったことは認識しています。

そのため、 operator= オーバーロードに std::copy を使用して、あるマップの内容を別のマップにコピーしました。これがノーノーであることを私はほとんど知りませんでした。

問題の領域を分離するために、クラス全体を行ごと、関数ごとに再構築することで、最終的にこれを発見しました。

次に、問題の領域を調べてグーグルで調べると、stackoverflow がこの質問と回答で救助に来ました。

次のステートメントは違法ですが、VS2012 IDE ではエラーとして強調表示されず、コンパイラーはそれを問題のあるステートメントとして識別しません。

std::copy( map1.begin(), map1.end(), map2.begin() );

前に強調表示された SO 回答が示すように、これを行う正しい方法は挿入ステートメントを使用することです。

map2.insert( map1.begin(), map1.end() );

これが誰かに役立つことを願っています:)

于 2012-11-09T12:52:38.953 に答える
2

このコードは GCC で正常にコンパイルされます:

#include <map>
#include <memory>
using namespace std;

typedef int AssetId;
struct Material {
    int _id;
    Material(int id) : _id(id) {}
    int AssetId() const { return _id; }
};
typedef std::map< AssetId, std::shared_ptr<Material> > MaterialsMap;    

MaterialsMap  m_materials;

int main() {
    std::shared_ptr<Material> pMaterial(new Material(42));
    m_materials.insert( MaterialsMap::value_type(pMaterial->AssetId(), pMaterial) );
}

あなたの例が不完全または間違っているか、これは MSVC2012 の標準ライブラリの実装のバグです。上記のコードでは呼び出しません。operator=

于 2012-11-05T11:34:51.090 に答える