Reputation: 6566
Please watch this:
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;
};
When I change the std::map<TK,TV>::const_iterator iter
to std::map<TK,TV>::iterator
it is causing the following compile error:
error C2440: 'initializing' : cannot convert from stlpd_std::priv::_DBG_iter<_Container,_Traits> to stlpd_std::priv::_DBG_iter<_Container,_Traits>
Can anyone exmplain why? I am not modifying the m_Map. Why the compiler is complaining??
Upvotes: 1
Views: 237
Reputation: 490808
The "why" is fairly simple.
The const
here:
TV Get(TK key) const
^^^^^
...means that this
is a Mediator const *
. That means you can't modify any of its contents, which is enforced through the type system by preventing you from assigning directly or obtaining a non-const reference, pointer, iterator, etc., to the content1.
The bad part is that the error message you're getting it, quite frankly terrible. I recognize it well as one MS VC++ used to generate on quite a regular basis. About the only "why" I can give here is that it simply did a poor job of reporting this type of error. About the only cure of which I'm aware is to use a different compiler. In this case, it's probably easiest to update to a newer version of MS VC++. The error messages in VC++ 2017 are much better.
const
-ness. The compiler tries to protect you from mistakes, but if you actively bypass its protection with a cast, you're pretty much on your own.Upvotes: 3
Reputation: 15585
Your MetaAssociator::Get
method is marked as const
, hence the field m_Map
is also const
in this method. Now, std::map::find
can only return a const_iterator
if the map itself is const
.
This makes sense - why would you return non-const iterators to a const collection?
Upvotes: 4
Reputation: 4024
Your function Get
is defined as const
which means that access to any local properties have to be constant. ::iterator
isn't constant but ::const_iterator
is.
Here is something I found with a quick google search that may help you understand. https://www.studytonight.com/cpp/const-keyword.php
Just use const_iterator and you'll be fine. The compiler doesn't care if you actually modify the value, it only checks wether or not the values are constant or not.
Upvotes: 1