【问题标题】:Error trying to make a wrapper of the STL map container尝试制作 STL 地图容器的包装时出错
【发布时间】:2025-12-08 19:00:01
【问题描述】:

我正在尝试对 STL 映射容器进行包装,以便添加一个 const 方法来返回给定键的值。在 map 中,operator[] 不是 const,find() 需要取消引用才能获取值 (map.find()->second)。顺便说一句,我的一些“研究”基于Idiomatic C++ for reading from a const map

到目前为止的代码(都在一个头文件中):

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

当我尝试编译它时,我收到以下错误:

在成员函数 `V easymap::get(K)' 中: 预期的';'在“迭代”之前 `iter' 未在此范围内声明 `end' 没有依赖于模板形参的参数,因此必须有 `end' 的声明| (如果你使用 `-fpermissive',G++ 将接受你的代码,但不允许使用未声明的名称)

我尝试这样做是否有意义?如果是这样,我该如何进行这项工作?如果没有,我将如何实现我正在寻找的效果?

【问题讨论】:

  • 也看看this线程。
  • 请注意,该线程中接受的答案只是将其实现为免费功能。 map.get(x);get(map, x); 之间并没有太大区别 - 您还忘记了映射还有两个模板参数(谓词和分配器)。

标签: c++ templates stl map constants


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    您缺少映射的模板参数,您必须在声明迭代器时指定typename(请参阅here),并且由于某种我不知道的原因(可能是命名空间冲突),您必须使用this拨打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();
        }
    };
    

    【讨论】:

    【解决方案3】:

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

    原因是,没有一个 STL 容器具有 virtual 析构函数。因此,如果您有一个指针,例如std::map&lt;..&gt; *,它指向您的对象(继承了map),则将调用其中一个析构函数。这是 100% 的内存泄漏。

    与此相关的问题是:Is it okay to inherit implementation from STL containers, rather than delegate?

    【讨论】:

    • 您多久动态分配一次 STL 容器?
    最近更新 更多