尝试制作 STL 地图容器的包装器时出错

发布于 2024-09-27 15:17:13 字数 1087 浏览 8 评论 0原文

我正在尝试为 STL 映射容器创建一个包装器,以便添加一个 const 方法来返回给定键的值。在map中,operator[]不是const,并且find()需要取消引用才能获取值(map.find()->second)。我的一些“研究”基于 惯用的 C++ 阅读顺便说一句,来自 const 映射

到目前为止的代码(全部位于单个头文件中):

#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));
        return iter != end() ? iter->second : V();
    }
};

当我尝试编译此代码时,出现以下错误:

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)

我尝试执行此操作的方式有意义吗?如果是这样,我该如何进行这项工作?如果没有,我该如何实现我想要的效果?

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));
        return 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

刘备忘录 2024-10-04 15:17:13

不要从 std::map 派生。相反,请在 easymap 中包装一个 std::map 实例,遵循先组合后继承的原则。除了所有技术原因之外,这更好地反映了设计意图:提供一个简化的 API 来映射隐藏默认 API:

template<typename K, typename V>
class easymap {
 std::map<K, V> mMap;
public:
  V Get(K Key) const {
   // ...
  }
};

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 {
   // ...
  }
};
墟烟 2024-10-04 15:17:13

您缺少映射的模板参数,在声明迭代器时必须指定 typename (请参阅 此处),并且由于某种我不知道的原因(可能是命名空间冲突),您在调用 end() 时必须使用 this

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();
    }
};

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();
    }
};
ι不睡觉的鱼゛ 2024-10-04 15:17:13

使用 STL 容器作为基类并不是一个好主意。您应该有充分的理由这样做并且要非常小心。

原因是,所有 STL 容器都没有虚拟析构函数。因此,如果您有一个指针,例如 std::map<..> *,指向您的对象(继承了map),析构函数之一将不会被调用。这是 100% 的内存泄漏。

与此相关的问题是:是可以从 STL 容器继承实现,而不是委托吗?

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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文