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

Why map::iterator causing compile error. C++

请看这个:

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。为什么编译器会报错??

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

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

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

您的 MetaAssociator::Get 方法被标记为 const,因此字段 m_Map 在该方法中也是 const。现在,如果地图本身是 const.

std::map::find 只能 return 一个 const_iterator

这是有道理的 - 为什么要 return non-const 迭代器到 const 集合?

"why" 相当简单。

这里的const

TV Get(TK key) const
               ^^^^^

...意味着 this 是一个 Mediator const *。这意味着你不能修改它的任何内容,这是通过类型系统强制执行的,阻止你直接分配 获得 non-const 引用、指针、迭代器等.,到内容1.

不好的部分是您收到的错误消息,坦率地说非常糟糕。我很清楚它是一个 MS VC++ 过去经常生成的。我在这里唯一可以给出的 "why" 是它在报告此类错误方面做得很差。据我所知,唯一的解决方法是使用不同的编译器。在这种情况下,更新到较新版本的 MS VC++ 可能是最简单的方法。 VC++ 2017 中的错误消息


  1. 尽管仍然可以通过(例如)获取指针或对 const 的引用来绕过此保护,然后再丢弃 const-ness。编译器试图保护您免受错误,但如果您主动通过强制转换绕过它的保护,您就只能靠自己了。