删除模板运算符中的"const int"限定符[]

Dropping "const int" qualifiers in template operator[]

本文关键字:int const 运算符 删除      更新时间:2023-10-16

我看过几篇关于const限定符的文章,但我不知道如何解决这个问题。我正在构建一个以STL映射类为模型的类,并且我使用STL集类作为基类:

template <class Key, class Value>
class map : public std::set <std::pair<Key, Value> > {
public:
    typedef std::set<std::pair<Key, Value> > parent;
    typedef typename std::set<std::pair<Key, Value> >::iterator iterator;
    // constructors
    map() : parent() {}
    map(map<Key, Value>& m) : parent(m) {}
    // definition for subscript operator
    Value& operator [] (const Key &);
    // overloaded methods from set
    void erase(Key&);
    void erase(iterator& itr) {
        parent::erase(itr);
    }
    int count(Key&);
    iterator find(Key&);
    iterator lower_bound(Key& k) {
        return parent::lower_bound(k);
    }
    iterator upper_bound(Key& k) {
        return parent::upper_bound(k);
    }
    // not found iterator
    iterator end() {
        return parent::end();
    }
};

问题在于operator[]重载函数,它看起来像:

template <class Key, class Value>
Value&  map<Key, Value>::operator[] (const Key& k) {
    std::pair<Key, Value> test;
    test.first = k;
    std::pair<iterator, bool> where = parent::insert(test);
    return (*(where.first)).second;
}

编译器给了我错误"…map.h:108:16:将引用绑定到类型'int'到类型'const int'的值会降低限定符"。我意识到它正在看到(*(where.first))。第二个被求值为"const int",我将其返回为"int",因为我已经将map声明为:

map<std::string, int> mymap;
mymap["one"] = 1;

似乎std::pair<...>被定义为std::pair<std::string, const int>而不是std::pair<std::string, int>。至少这是我的猜想。我一定错过了一些简单的东西,但我没有看到它。如有任何帮助,不胜感激。

问题是std::set元素是不可变的(否则您可以任意修改它们并在set不知道的情况下混乱排序);这是通过它的方法返回const迭代器来实现的。

因此,*(where.first)const,因此(*(where.first)).second也是。所以你不能返回一个非const的引用。