如何获得支持负索引的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] 时,它指向向量的第一个元素。

你不能在 中使用负索引,除非 提供你自己的 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