如何在这个定制的容器中使用`std :: lower_bound`?

时间:2018-04-10 19:28:51

标签: c++ algorithm oop search iterator

我想要一个std::vector<std::vector<T>>对象的包装器。以下是Wrapper

下实施的一些基本方法
template<class T>
class Wrapper
{
private:
    std::vector<std::vector<T>>& data;
    int totalSize;
    std::vector<int> indicesMap;

public:
    Wrapper(std::vector<std::vector<T>>& input):data(input)
    {
        totalSize = 0;
        for (int i = 0 ; i < data.size() ; i++)
        {
            totalSize += data[i].size();
            indicesMap.push_back(totalSize);
        }
    }

    T operator[](int index)
    {
        int whichVector = std::upper_bound(
            indicesMap.begin(),
            indicesMap.end(),
            index
        ) - indicesMap.begin();

        int i = whichVector == 0 ? index : index - indicesMap[whichVector-1];

        return data[whichVector][i];
    }

    int size()
    {
        return totalSize;
    }
};

这是一个简单的测试

int main()
{
    std::vector<std::vector<int>> x;
    std::vector<int> x1 = {1,2,3};
    std::vector<int> x2 = {10,20,30};
    std::vector<int> x3 = {100,200,300};
    x.push_back(x1);
    x.push_back(x2);
    x.push_back(x3);

    Wrapper<int> w(x);
    std::cout << w[4] << "\n"; // prints 20 as expected

    return 0;
}

我希望能够在对象upper_bound上使用lower_boundWrapper。我并不真正理解如何为自定义对象创建迭代器,但却未能实现它,即便如此,我也不确定将存在和结束迭代器赋予lower_bound是否可行。

您能否帮助我为对象upper_bound实施lower_boundWrapper

我的目标是能够做到

std::lower_bound(w.begin(), w.end(), object);

1 个答案:

答案 0 :(得分:1)

您必须为满足概念ForwardIterator的包装器创建和实现迭代器。有关如何执行此操作的详细信息,请参阅此主题的答案How to correctly implement custom iterators and const_iterators?。然后提供首先返回并在过去迭代器后面返回的包装器的方法(通常它们称为begin()end(),它们最好是你可以按照你想要的方式调用它们。

Iterator可以std::pair<size_t,size_t>实现,其中data的位置加上data本身的引用,并operator++正确实现。

可选择进行优化,您可能希望使迭代器满足RandomAccessIterator概念,std::lower_boundstd::upper_bound可能更有效(取决于您实现随机访问的方式)。< / p>