我真正想要的是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,但它的行为并不是这样。
答案 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