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-value 指定 const 对象 c:\program files (x86)\microsoft visual studio 11.0\vc\include\utility 114

谁能解释我如何解决这个问题?

4

2 回答 2

3

我在这个问题上扯了我的头发,我可能花了一个星期的时间。幸运的是,它对项目路线图并不重要,因此并没有阻止继续进行。

该问题与编译器无关,尽管错误报告可能与增强有关,尽管我意识到这一直是模板(和 STL)代码的问题。

所以我有一个 std::copy 在我的 operator= 重载中将一个地图的内容复制到另一个地图。我几乎不知道这是一个禁忌。

为了隔离问题区域,我最终通过逐行和逐个函数地重新构建整个类来发现这一点。

然后通过检查问题区域和谷歌搜索,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 回答