如何获得支持负索引的std :: vector?

时间:2016-07-14 19:05:23

标签: c++ vector indexing stl c++-standard-library

我有一个矢量。我想要做的是在向量的第一个索引处存储一个值。但是,此值是针对错误的,因此我想将此值称为vector_ [-1]。我该怎么做呢?

我提出了一个解决方案。 我正在做的是创建一个新的向量并将新向量分配给此向量。

vector_.resize(required_size+1);
vector_ = std::vector<T> (vector_.begin()+1,vector_.end());

此时我可以合法使用vector_[-1]吗?如果没有,请帮助我解决其他问题。

修改 我找到了一个解决方法。虽然它不是具有负索引的向量,但我使用了指向向量的第二个成员的指针,因此当我执行ptr[-1]时,它指向向量的第一个元素。

3 个答案:

答案 0 :(得分:2)

中不能有负面索引,除非提供自己的一个衰减的矢量类。

例如,检查ref

  

原型:reference operator[] (size_type n);

     

参数:n位置   容器中的元素。请注意,第一个元素有一个   位置0(不是1)。成员类型size_type是无符号整数   类型。

这是一个可以做你想做的课:

// 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

答案 1 :(得分:1)

我不明白你为什么要这样做。您还可以将额外值存储在第一个元素中,然后通过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索引。

答案 2 :(得分: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