插入std :: map时的constness问题

时间:2012-11-05 11:23:05

标签: c++ const stdmap visual-c++-2012

尝试将一对插入地图时,我遇到了一个constness问题。编译器错误是:

              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

任何人都可以解释我是如何解决这个问题的吗?

2 个答案:

答案 0 :(得分:3)

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

问题与编译器无关,虽然错误报告可以用增强功能,但我意识到这一直是模板(和STL)代码的问题。

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

我终于通过逐行构建整个班级,逐行构建和逐个函数来找到它,以便隔离问题区域。

然后通过检查问题区域和谷歌搜索,stackoverflow使用此question and answer来解救。

虽然以下声明是非法的,但它不会在VS2012 IDE中突出显示为错误,编译器也不会将其标识为问题声明。

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

正如之前强调的SO答案所述,正确的方法是使用insert语句:

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

我希望这可以帮助那些人:)

答案 1 :(得分:2)

此代码compiles fine with 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=