如何获得支持负索引的std::vector?
How to get a std::vector that supports negative indices?
我有一个向量。我想要做的是在向量的第一个索引处存储一个值。但是,这个值是针对错误的,所以我想像 vector_ [-1]
这样引用这个值。我该怎么做?
我想到了一个解决方案。
我正在做的是创建一个新向量并将新向量分配给这个向量。
vector_.resize(required_size+1);
vector_ = std::vector<T> (vector_.begin()+1,vector_.end());
此时我可以合法使用 vector_[-1]
吗?如果不行,请帮我解决其他问题。
编辑
我找到了解决方法。虽然它不是带有负索引的向量,但我使用的是指向向量第二个成员的指针,所以当我执行 ptr[-1]
时,它指向向量的第一个元素。
你不能在 c++-standard-library 中使用负索引,除非 你 提供你自己的 class衰减的矢量。
例如,检查 ref:
Prototype: reference operator[] (size_type n);
Parameters: n Position
of an element in the container. Notice that the first element has a
position of 0 (not 1). Member type size_type is an unsigned integral
type.
这里有一个 class 可以做你想做的事:
// Example program
#include <iostream>
#include <string>
#include <vector>
class myVector {
public:
int get(int index) { return v[index + 1]; }
void push_back(int value) { v.push_back(value); }
void print() {
for(unsigned int i = 0; i < v.size(); ++i)
std::cout << v[i] << " ";
std::cout << "\n";
}
const int& operator[](int index) const { return v[index + 1]; }
private:
std::vector<int> v;
};
int main() {
myVector v;
v.push_back(404); // error code
v.push_back(32); // real data
v.print();
std::cout << v[-1] << std::endl;
std::cout << v.get(-1) << std::endl;
return 0;
}
输出(Live Demo):
404 32
404
404
由于您是 C++ 新手,运算符重载可能会让您感到困惑,暂时跳过它,稍后再回来阅读 Operator overloading。
我不明白你为什么要这样做。您也可以将额外值存储在第一个元素中并通过 vector_[0]
访问它。但是,如果您坚持使用 -1 作为索引,那么我只看到一种正确的方法:
template<typename T>
class {
public:
T& operator[](int index){
if (index==-1) { return value; }
else { return vector[index]; }
}
private:
T value;
std::vector<T> vector;
}
但是,我强烈建议不要开始这样的事情。您将浪费大量代码来获得类似于矢量的东西,而您可以简单地使用普通 std::vector
而忘记 -1 索引。
这是向量的基本起点,您可以在其中指定(有符号的)上下索引
#include <vector>
#include <cassert>
#include <iostream>
#include <iomanip>
template<class T>
struct any_index_vector
{
any_index_vector(int min, int max)
: _zero_index(min)
, _storage((max - min))
{
// assert min - max
}
T& operator[](int index)
{
assert(index >= lower_limit());
assert(index <= upper_limit());
return _storage[index - _zero_index];
}
T& operator[](int index) const
{
assert(index >= lower_limit());
assert(index <= upper_limit());
return _storage[index - _zero_index];
}
int upper_limit() const {
return _zero_index + int(_storage.size());
}
int lower_limit() const {
return _zero_index;
}
int extent() const {
return upper_limit() - lower_limit();
}
int _zero_index = 0;
std::vector<T> _storage {};
};
int main()
{
any_index_vector<int> v(-1, 9);
for (int i = -1 ; i < 10 ; ++i) {
v[i] = (i+6);
}
for (int i = -1 ; i < 10 ; ++i) {
std::cout << "position: " << std::setw(2) << i << " : " << v[i] << std::endl;
}
}
预期输出:
position: -1 : 5
position: 0 : 6
position: 1 : 7
position: 2 : 8
position: 3 : 9
position: 4 : 10
position: 5 : 11
position: 6 : 12
position: 7 : 13
position: 8 : 14
position: 9 : 15
我有一个向量。我想要做的是在向量的第一个索引处存储一个值。但是,这个值是针对错误的,所以我想像 vector_ [-1]
这样引用这个值。我该怎么做?
我想到了一个解决方案。 我正在做的是创建一个新向量并将新向量分配给这个向量。
vector_.resize(required_size+1);
vector_ = std::vector<T> (vector_.begin()+1,vector_.end());
此时我可以合法使用 vector_[-1]
吗?如果不行,请帮我解决其他问题。
编辑
我找到了解决方法。虽然它不是带有负索引的向量,但我使用的是指向向量第二个成员的指针,所以当我执行 ptr[-1]
时,它指向向量的第一个元素。
你不能在 c++-standard-library 中使用负索引,除非 你 提供你自己的 class衰减的矢量。
例如,检查 ref:
Prototype:
reference operator[] (size_type n);
Parameters: n Position of an element in the container. Notice that the first element has a position of 0 (not 1). Member type size_type is an unsigned integral type.
这里有一个 class 可以做你想做的事:
// Example program
#include <iostream>
#include <string>
#include <vector>
class myVector {
public:
int get(int index) { return v[index + 1]; }
void push_back(int value) { v.push_back(value); }
void print() {
for(unsigned int i = 0; i < v.size(); ++i)
std::cout << v[i] << " ";
std::cout << "\n";
}
const int& operator[](int index) const { return v[index + 1]; }
private:
std::vector<int> v;
};
int main() {
myVector v;
v.push_back(404); // error code
v.push_back(32); // real data
v.print();
std::cout << v[-1] << std::endl;
std::cout << v.get(-1) << std::endl;
return 0;
}
输出(Live Demo):
404 32
404
404
由于您是 C++ 新手,运算符重载可能会让您感到困惑,暂时跳过它,稍后再回来阅读 Operator overloading。
我不明白你为什么要这样做。您也可以将额外值存储在第一个元素中并通过 vector_[0]
访问它。但是,如果您坚持使用 -1 作为索引,那么我只看到一种正确的方法:
template<typename T>
class {
public:
T& operator[](int index){
if (index==-1) { return value; }
else { return vector[index]; }
}
private:
T value;
std::vector<T> vector;
}
但是,我强烈建议不要开始这样的事情。您将浪费大量代码来获得类似于矢量的东西,而您可以简单地使用普通 std::vector
而忘记 -1 索引。
这是向量的基本起点,您可以在其中指定(有符号的)上下索引
#include <vector>
#include <cassert>
#include <iostream>
#include <iomanip>
template<class T>
struct any_index_vector
{
any_index_vector(int min, int max)
: _zero_index(min)
, _storage((max - min))
{
// assert min - max
}
T& operator[](int index)
{
assert(index >= lower_limit());
assert(index <= upper_limit());
return _storage[index - _zero_index];
}
T& operator[](int index) const
{
assert(index >= lower_limit());
assert(index <= upper_limit());
return _storage[index - _zero_index];
}
int upper_limit() const {
return _zero_index + int(_storage.size());
}
int lower_limit() const {
return _zero_index;
}
int extent() const {
return upper_limit() - lower_limit();
}
int _zero_index = 0;
std::vector<T> _storage {};
};
int main()
{
any_index_vector<int> v(-1, 9);
for (int i = -1 ; i < 10 ; ++i) {
v[i] = (i+6);
}
for (int i = -1 ; i < 10 ; ++i) {
std::cout << "position: " << std::setw(2) << i << " : " << v[i] << std::endl;
}
}
预期输出:
position: -1 : 5
position: 0 : 6
position: 1 : 7
position: 2 : 8
position: 3 : 9
position: 4 : 10
position: 5 : 11
position: 6 : 12
position: 7 : 13
position: 8 : 14
position: 9 : 15