【问题标题】:Implementation of a contiguous (flat) unordered container连续(扁平)无序容器的实现
【发布时间】:2017-04-04 22:25:40
【问题描述】:

我正在尝试实现或从概念上设计一个具有连续内存但元素顺序不重要的容器(并且用于插入/删除对象)。

这类似于std::vector,但解除了当一个元素被移除时,其他元素的相对顺序被保留的约束,因为在这种情况下,最后一个元素可以代替被移除的元素.

我或多或少知道如何实现它(基于std::vector 和一些特殊的反向引用iterator)但我正在寻找一个参考实现以避免重新发明轮子。 p>

我对Boost.Container很熟悉,但是我没有找到这样的容器。 boost::container::flat_set 很接近,但它保持顺序,这是不必要的。从某种意义上说,我正在寻找某种“boost::container::unordered_flat_set”或“unordered_vector”。

这是我期望的行为:

unordered_flat_set<T> ufs(100); // allocates 100 elements
ufs.reserve(120);

unordered_flat_set<T>::iterator it = ...; // find something
ufs.erase(it); // overwrite last element to that position, destroy last element
ufs.insert(T{}); //add element at "end", only if necessary reallocate, keep buffer memory in multiples of 2 (or 1.6). Element order is not fundamental, can be altered completely by a call to "erase".
ufs.size(); // report size

eraseinsert 都是 O(1),(除非需要重新分配)。

这是一个尚未出现在标准或非标准容器中的概念吗? (也许是无序的概念不能很好地与当前的容器配合使用。 毕竟目前唯一的“无序”是std::unordered_set,而且是相当新的。)

这是一个参考(非常最小)的实现,主要是给出我正在寻找的概念的具体实现。事实上,我正在寻找这个概念是否已经存在以将其应用于现有的基本代码。 我并不是要重新发明轮子。

#include<iostream>
#include<vector>

template<class T>
class unordered_vector{
    std::vector<T> impl_;
    public:
    unordered_vector(){}
    void reserve(int i){impl_.reserve(i);}
    struct iterator{
        std::vector<T>* back_ptr;
        int i;
        T& operator*(){return back_ptr->operator[](i);}
        iterator operator++(){++i; return *this;}
        iterator operator--(){--i; return *this;}
        bool operator==(iterator const& other) const{return back_ptr == other.back_ptr and i == other.i;}
        bool operator!=(iterator const& other) const{return not(*this == other);}
    };
    int size(){return impl_.size();}
    iterator erase(iterator it){
        *it = it.back_ptr->last(); // should I use placement new here to not rely in customized (or not assignable object type)?
        return it.back_ptr->erase(it.rbegin()); // I return this for compatibility, although there is no use for this
    }
    iterator insert(T t){
        impl_.push_back(t); return {&impl_, size()-1};
    }
    iterator begin(){return {&impl_, 0};} // does an unordered container have a begin ?? ok, for compatibility, like std::unordered_set
    iterator end(){return {&impl_, (int)impl_.size()};} // same question,
    T& operator[](int i){return impl_[i];} // same question, if it is unordered v[i] has not a "salient" meaning.
};

int main(){

    unordered_vector<double> uv;
    uv.reserve(10);
    uv.insert(1.1);
    uv.insert(2.3);
    uv.insert(5.4);
    uv.insert(3.1);
    std::cout << uv.size() << std::endl;
    auto it = uv.begin();
    assert( uv.begin() != uv.end());
    assert( it != uv.end() );
    for(auto it = uv.begin(); it != uv.end(); ++it){
        std::cout << *it << std::endl;
    }
}

【问题讨论】:

  • “解除限制,即当一个元素被移除时,最后一个元素可以被移除的元素交换”——我认为你的意思是“不能”而不是“可以”。
  • 您的问题,就目前而言,是题外话,因为它要求一些外部资源。不过,潜在的问题很有趣。也许您可以对其进行调整以使其适合 SO?
  • @DanielJour,感谢您的提示。我修改了问题。我正在使用我自己的参考实现来展示一些工作并开始一些讨论。告诉我。
  • 我在这里发现了几乎相同的讨论:stackoverflow.com/questions/30937987/…

标签: c++ boost stl containers


【解决方案1】:

请查看我最近更新到 GitHub 的 sfl 库: https://github.com/slavenf/sfl-library

它是 C++11 仅标头库,提供平面有序和无序容器,可将元素连续存储在内存中。所有容器均满足ContainerAllocatorAwareContainerContiguousContainer 的要求。

【讨论】:

    猜你喜欢
    • 2011-09-18
    • 2018-01-17
    • 1970-01-01
    • 2016-11-20
    • 2017-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多