请看这个:
template<typename TK, typename TV>
class MetaAssociator
{
public:
void Set(TK key, TV const & value)
{
boost::lock_guard<boost::mutex> lock(m_Mutex);
m_Map[key] = value;
}
TV Get(TK key) const
{
boost::lock_guard<boost::mutex> lock(m_Mutex);
std::map<TK,TV>::const_iterator iter = m_Map.find(key);
return iter == m_Map.end() ? TV() : iter->second;
}
private:
mutable boost::mutex m_Mutex;
std::map<TK,TV> m_Map;
};
当我将std::map<TK,TV>::const_iterator iter
更改为std::map<TK,TV>::iterator
时,会导致以下编译错误:
error C2440: 'initializing' : cannot convert from stlpd_std::priv::_DBG_iter<_Container,_Traits> to stlpd_std::priv::_DBG_iter<_Container,_Traits>
任何人都可以解雇为什么?我没有修改m_Map。为什么编译器抱怨?
答案 0 :(得分:4)
您的MetaAssociator::Get
方法被标记为const
,因此此方法中的字段m_Map
也是const
。现在,如果地图本身为std::map::find
,则const_iterator
只能返回const
。
这是有道理的 - 为什么要将非const迭代器返回到const集合?
答案 1 :(得分:3)
&#34;为什么&#34;很简单。
此处const
:
TV Get(TK key) const
^^^^^
...表示this
是Mediator const *
。这意味着您无法修改任何内容,这是通过类型系统强制执行的,因为它阻止您直接指定或获取非const引用,指针,迭代器等。内容 1 。
不好的部分是你得到它的错误信息,非常坦率地说是可怕的。我很清楚,因为一个MS VC ++经常用于定期生成。关于唯一的&#34;为什么&#34;我可以在这里说,它只是报告这种类型的错误很糟糕。关于我唯一知道的解决方法是使用不同的编译器。在这种情况下,最简单的方法是更新到更新版本的MS VC ++。 VC ++ 2017中的错误消息很多更好。
const
- ness。编译器会试图保护您免受错误的影响,但是如果您通过演员表主动绕过它的保护,那么您自己就可以了。答案 2 :(得分:1)
您的函数Get
定义为const
,这意味着对任何本地属性的访问必须是不变的。 ::iterator
不是常数,::const_iterator
是。
以下是我通过快速谷歌搜索找到的可能有助于您理解的内容。 https://www.studytonight.com/cpp/const-keyword.php
只需使用const_iterator就可以了。编译器并不关心您是否实际修改了值,它只检查值是否为常量。