为什么map :: iterator导致编译错误。 C ++

时间:2018-04-09 14:02:50

标签: c++ const stdmap

请看这个:

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。为什么编译器抱怨?

3 个答案:

答案 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
               ^^^^^

...表示thisMediator const *。这意味着您无法修改任何内容,这是通过类型系统强制执行的,因为它阻止您直接指定获取非const引用,指针,迭代器等。内容 1

不好的部分是你得到它的错误信息,非常坦率地说是可怕的。我很清楚,因为一个MS VC ++经常用于定期生成。关于唯一的&#34;为什么&#34;我可以在这里说,它只是报告这种类型的错误很糟糕。关于我唯一知道的解决方法是使用不同的编译器。在这种情况下,最简单的方法是更新到更新版本的MS VC ++。 VC ++ 2017中的错误消息很多更好。

  1. 虽然仍然可以通过(例如)获取指针或const的引用来绕过这种保护,然后再抛弃const - ness。编译器会试图保护您免受错误的影响,但是如果您通过演员表主动绕过它的保护,那么您自己就可以了。

答案 2 :(得分:1)

您的函数Get定义为const,这意味着对任何本地属性的访问必须是不变的。 ::iterator不是常数,::const_iterator是。

以下是我通过快速谷歌搜索找到的可能有助于您理解的内容。 https://www.studytonight.com/cpp/const-keyword.php

只需使用const_iterator就可以了。编译器并不关心您是否实际修改了值,它只检查值是否为常量。