包含随机访问的C ++向量?

时间:2016-07-12 15:41:40

标签: c++ inheritance boost vector stl

我真正想要的是C ++中的容器类,除了[]运算符具有包装行为外,它与各种方式的STL向量类完全相同。例如:

vector<int>  myVec;
myVec.push_back(5);
myVec.push_back(10);
myVec.push_back(15);

cout << myVec[ 5] << endl;   // would output 15
cout << myVec[ 1] << endl;   // would output 10
cout << myVec[-2] << endl;   // would output 10

这样的容器是否已经存在,或者是否可以在向量模板中重载或重新定义[]运算符?

我见过Boost circular buffer,但它的行为并不是这样。

3 个答案:

答案 0 :(得分:3)

  

此类容器是否已存在

至少不在标准库中。

  

是否可以在矢量模板中重载或重新定义[]运算符?

不,您不能重载或重新定义std::vector的[]运算符。

当然可以编写一个包含重载T& operator[](int pos)的包装器,它具有您描述的行为。像这样:

T& operator[](int pos) {
    std::vector<T>::size_type fancy_pos =
        pos < 0 ? data.size() + pos
                : pos - 1;
    return data[fancy_pos];
}

答案 1 :(得分:1)

在C ++中,容器的索引从0开始。

你可以将标准容器std :: vector包装在一个类中并重载operator [],使得索引的计算方式如index = index % size()index %= size()

答案 2 :(得分:1)

您正在寻找循环缓冲区或循环缓冲区。

Boost有他们:

他们有时非常表现得比例如使用std :: deque滚动自己,请参阅ASIO的这个示例:

更新

我维护boost :: circular_buffer可能是您/应该想要的/ - 因为它抽象了您通常想要的大多数任务的“方式”。但是,创建自己的适配器类型非常简单:

<强> Live On Coliru

#include <vector>

namespace mylib {
    template <typename T, typename Container = std::vector<T> >
    struct circular : Container {
        using Container::Container;
        using Container::operator =;

        auto& operator[](int i) const {
            // mixed signed/unsigned modulo is undefined
            while (i<0) i += Container::size();
            return Container::operator[](i % Container::size());
        }

        auto& operator[](int i) {
            while (i<0) i += Container::size();
            return Container::operator[](i % Container::size());
        }
    };
}

#include <iostream>

template <typename Whatever>
void test(Whatever const& data) {
    std::cout << data[ 5] << ", "; // would output 15
    std::cout << data[ 1] << ", "; // would output 10
    std::cout << data[-2] << std::endl; // would output 10
}

#include <string>
#include <deque>
int main() {
    test(mylib::circular<int>                                   { 5, 10, 15                }); 
    test(mylib::circular<std::string>                           { "five", "teen", "fiteen" }); 
    test(mylib::circular<std::string, std::deque<std::string> > { "five", "teen", "fiteen" }); 
    test(mylib::circular<int, std::deque<float> >               { 5, 10, 15                }); 
}

打印:

15, 10, 10
fiteen, teen, teen
fiteen, teen, teen
15, 10, 10