Error trying to make a wrapper of the STL map container
I'm trying to make a wrapper to the STL map container, in order to add a const method to return the value given the key. In map, operator[] isn't const, and find() requires dereferencing to get the value (map.find()->second). I'm basing some of my "research" off of Idiomatic C++ for reading from a const map by the way.
The code so far (all inside a single header file):
#include <map>
template <typename K, typename V>
class easymap : public std::map<K, V>
{
//Constructor
easymap() : std::map<K, V>() {};
//The get method
V get(K key)
{
std::map<K, V>::const_iterator iter(find(key));
r开发者_高级运维eturn iter != end() ? iter->second : V();
}
};
When I try to compile this, I get the following errors:
In member function `V easymap::get(K)': expected `;' before "iter" `iter' was not declared in this scope there are no arguments to `end' that depend on a template parameter, so a declaration of `end' must be available| (if you use `-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated)
Does how I'm trying to go about doing this make sense? If so, how do I make this work? If not, how would I go about achieving the effect I'm looking for?
Do not derive from std::map
. Rather, wrap a std::map
instance in your easymap
, following the composition before inheritance principle. Besides of all the technical reasons, this reflects the design intent much better: provide a simplified API to map hiding the default one:
template<typename K, typename V>
class easymap {
std::map<K, V> mMap;
public:
V Get(K Key) const {
// ...
}
};
You are missing the template parameters for map, you have to specify typename
when declaring the iterator (see here), and for some reason unknown to me (probably a namespace conflict) you have to use this
when calling end()
:
template <typename K, typename V>
class easymap : public std::map<K,V>
{
//Constructor
easymap() : std::map<K, V>() {};
//The get method
V get(K key)
{
typename std::map<K, V>::const_iterator iter(find(key));
return iter != this->end() ? iter->second : V();
}
};
It's no a good idea to use STL container as base class. You should have a really good reason to do that and to be very careful.
The reason is, that none of the STL containers have a virtual
destructor. So, if you have a pointer, for example std::map<..> *
, that points to your object (that has inherited the map
), one of the destructors will not be called. This is a 100% memory leak.
Related question to this one is: Is it okay to inherit implementation from STL containers, rather than delegate?
精彩评论