std :: pair并在地图实现中复制分配它

时间:2018-07-09 20:56:42

标签: c++ iterator

让我首先为您提供基本的关联数组实现。

#include <utility>
#include <functional>
#include <vector>
#include <algorithm>
#include <iostream>

namespace chops {
template <typename Key, typename Value,
          typename Compare = std::less<Key>>
struct map {
    using value_type = std::pair<const Key, Value>;
    using key_type = Key;
    using mapped_type = Value;
    using size_type = std::size_t;
    using difference_type = std::ptrdiff_t;
    using key_compare = Compare;
    using reference = value_type&;
    using const_reference = value_type const&;
    using iterator = typename std::vector<value_type>::iterator;
    using const_iterator = typename std::vector<value_type>::const_iterator;

    iterator begin() {
        return data.begin();
    }

    iterator end() {
        return data.end();
    }

const_iterator begin() const {
    return data.begin();
}

const_iterator end() const {
    return data.end();
}

const_iterator cbegin() const {
    return data.cbegin();
}

const_iterator cend() const {
    return data.cend();
}

    size_type size() {
        return data.size();
    }

    bool empty() {
        return data.empty();
    }

    void clear() {
        data.clear();
    }

    mapped_type& operator[](Key const& k) {
        key_comp kc{k};
        iterator it = std::find_if(begin(), end(), kc);
        if(it == end()) {
            auto n = std::make_pair(k, mapped_type{});
            data.push_back(n);
            return data.back().second;
        } else
            return (*it).second;
    }

    template< class... Args >
    std::pair<iterator,bool> emplace(Args&&... args) {
        value_type v{std::forward<Args>(args)...};
        key_comp kc{v.first};
        iterator it = std::find_if(begin(), end(), kc);
        if(it == end()) {
            data.push_back(v);
            return std::make_pair(data.end()--, true);
        } else
            return std::make_pair(it, false);
    }

    void erase(iterator pos){
        data.erase(pos);
    }

private:
    struct key_comp {
        Key k;
        bool operator()(value_type const& p1) {
            return p1.first == k;
        }
    };
    std::vector<value_type> data;
};
}

int main() {
    chops::map<int, std::string> m1;
    m1[1] = "Burak";
    m1.emplace(2, "Kaan");
    m1.emplace(3, "Copur");

    for (auto& kv : m1) 
        std::cout << kv.first << " has value " << kv.second << std::endl;
    m1.erase(m1.begin());    
    for (auto& kv : m1) 
        std::cout << kv.first << " has value " << kv.second << std::endl;
}

首先,代码使用向量存储键值对。这使得实现起来很容易,但是操作不是像平衡树实现那样的O(log(n))或像基于哈希的实现那样的O(1)。实际上,从某种意义上讲,这是一个容器容器,外部容器可以在实现中进行参数设置。无论如何,我的问题是关于擦除功能的,我只是委托给底层矢量的擦除功能。编译器告诉我,复制构造函数已从对类型中删除,因为它具有用户定义的移动方式。擦除尝试在我猜到的擦除位置之后复制这些部分,并尝试在那里使用复制构造函数。

问题是,我设计了一个最小的示例,如下所示:

#include <vector>
#include <string>
#include <utility>

int main() {
    auto p1 = std::make_pair(1, "Burak");
    auto p2 = std::make_pair(2, "Kaan");

    std::vector<std::pair<int, std::string>> v1;
    v1.push_back(p1);
    v1.push_back(p2);

    v1.erase(v1.begin());
}

我可以轻松地从向量中删除它们。那么,在我的erase实现中,什么可能不起作用?

0 个答案:

没有答案