C++ 插入std::map时的常量问题

C++ 插入std::map时的常量问题,c++,constants,stdmap,visual-c++-2012,C++,Constants,Stdmap,Visual C++ 2012,我在尝试将一对插入地图时遇到了常量问题。编译器错误为: 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 s

我在尝试将一对插入地图时遇到了常量问题。编译器错误为:

              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_材料图声明如下:

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

MaterialsMap  m_materials;
typedef std::mapMaterialsMap;
typedef std::pairMtlPair;
材料地图m_材料;
错误1错误C2166:l值指定常量对象c:\program files(x86)\microsoft visual studio 11.0\vc\include\utility 114

谁能解释一下我是如何解决这个问题的

此代码:

#包括
#包括
使用名称空间std;
类型定义int AssetId;
结构材料{
内部id;
材料(内部id):\u id(id){}
int AssetId()常量{return\u id;}
};
typedef std::mapMaterialsMap;
材料地图m_材料;
int main(){
标准:共享材料(新材料(42));
m_materials.insert(MaterialsMap::value_type(pmatary->AssetId(),pmatary));
}

您的示例不完整或错误,或者这是MSVC2012标准库实现中的错误。在上面的代码中,它不应该调用
操作符=

我为这个问题大伤脑筋,大概花了一周的时间。幸运的是,它对项目路线图并不重要,因此它没有阻止继续

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

因此,我在operator=重载中使用std::copy将一个映射的内容复制到另一个映射。我一点也不知道这是个禁忌

我最终发现了这一点,再次构建整个类,一行一行,一个函数一个函数,以隔离问题区域

然后,通过检查问题区域和谷歌搜索,stackoverflow找到了解决办法

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

std::copy( map1.begin(), map1.end(), map2.begin() );
正如前面突出显示的SO答案所述,正确的方法是使用insert语句:

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

我希望这对其他人有所帮助:)

将数据插入
std::map
的标准方法是使用
std::make\u pair
,而不是
std::map::value\u type
@KirilKirov:
value\u type
。它属于
pair
类型,应该可以正常工作。如果不允许实现调用
操作符=
,那么这里只涉及复制构造函数。所以我猜:纯粹的软件缺陷。@ybungalobill-当然,我不是说,这就是问题所在,这就是为什么我添加它作为评论的原因。我的观点是,根据我的经验,我从未见过有人使用
map::value\u type
。但我没有那么多经验,所以我可能错了。谢谢你提供的信息。@KirilKirov:我有时更喜欢使用
value\u type
,因为这样我就不需要包含额外的标题了。(是不是
在哪里定义了
make\u pair
)@ybungalobill-我明白了。我从不包括
,当我包括
时,我认为它包括在那里或其他地方。唯一一次,我把
包括在内是当我使用
std::pair
而不是
std::map
时。或者他错误地引用了一些东西,或者这是其他地方的问题造成的。我经常将
std::map::value\u type
插入到映射中,但我不记得有过任何问题,包括Microsoft编译器。@JamesKanze:1)OP使用MSVC2012,这是一款全新的产品,我甚至还没有尝试过。2) 这不是“微软编译器”,而是一个“纯粹的软件库”。3) 有相当多的退化。例如,MSVC2010成功地破坏了
std::pair
。Dinkumware是(或至少是)Microsoft的库供应商,但库是编译器的一部分,当它与Microsoft编译器一起出现时,不管是谁编写的,它都是Microsoft库。我没有访问MSVC2012的权限,但我可以想象,添加对右值引用的支持所需的所有更改都会引入一些bug。(因为我的印象是微软没有测试他们提供的产品…@JamesKanze:对不起,这个库肯定不是编译器的一部分。您可以更改默认包含路径并禁用与默认库的链接,从而使用具有相同编译器的另一个库实现。这不是假设。我记得在内核模式中看到用第三方实现写C++ C++的方法,该库由C++标准定义,作为语言的一部分;标准中的第一句话说它定义了语言。当我购买或安装编译器时,它附带了库。你可以用选项做很多事情,这意味着你不再有C++编译器。
map2.insert( map1.begin(), map1.end() );