C++ 替换:用 v.at(x) 替换每次出现的 v[x]

C++ replacement: Replacing every occurence of v[x] with v.at(x)

在 C++ 中,对于向量 v,v.at(x) 的行为类似于 v[x],只是如果访问不存在的元素,它会抛出越界错误。

我想理想地总是使用v.at(x),但是,写起来不如v[x]方便。有没有办法让 v[x] 表现得像 v.at(x),也许使用像 #define?

这样的东西

如果不是,是否有更好的解决方案总是抛出越界错误?

可以考虑在新的继承中重载方法,如下

#include <iostream>
#include <vector>

template< class T, class allocator =  std::allocator<T>>
struct Vector : std::vector<T, allocator>{
    using std::vector<T, allocator>::vector;

    const T& operator[](size_t i)const{
        return this -> at(i);
    }

    T& operator[](size_t i){
        return this -> at(i);
    }
};

template< class T>
Vector(size_t, T ) -> Vector<T>;//if u want to use c++17 deduction guides

int main()
{
    std::vector<int> vec1(4,1);
    std::cout << vec1[4];

    Vector vec2(4,1);
    std::cout << vec2[4];

}

您可以使用带有调用方法 at() 的运算符 [] 的代理对象。当然,这不是您想要的,但语法是相似的:您必须写 at(v)[x].

而不是 v[x]

概念证明:

#include <iostream>
#include <vector>


template<class T>
class AtProxy
{
  public:
    AtProxy(const AtProxy<T>& proxy) : m_obj{proxy.m_obj} {}
    AtProxy(T& obj) : m_obj{obj} {}
    typename T::reference operator [](size_t index)
    {
      return m_obj.at(index);
    }
  private:
    T& m_obj;
};


template<class T>
AtProxy<T> at(T& v)
{
  return AtProxy<T>(v);
}


int main()
{
  try
  {
    std::vector<int> vec = {1,2,3,4,5};

    for(size_t i = 0; i < 5; i++)   
    {
      std::cout << i << std::endl;
      at(vec)[i] = at(vec)[i + 1] + 1;
    }   
  }
  catch(std::exception& e)
  {
    std::cout << "exception: " << e.what() << std::endl;
  }
   
  std::cout << "ok" << std::endl;
  return 0;
}