为自定义向量类重载operator []

时间:2012-11-24 14:11:54

标签: c++ vector

我正在创建一个类似于向量的类。它使用自己的算法来确定数据的实际存储位置和方式。从用户的角度来看,它就像一个普通的矢量一样工作。

在内部,它尝试通过不多次存储重复值来节省内存。如果将相同的值多次推送到矢量上,它会使用索引进行一些奇特的舞蹈动作,但只存储实际值一次。

当重载operator []时,index参数转换为" real"索引,以便它可以访问数据实际存储的位置。

如果用户试图访问这样的元素:

int i = svec[8];

通过将8转换为" real"返回正确的元素。索引和访问正确的元素。

当用户尝试分配如下值时会出现问题:

svec[8] = 1;

值8将再次覆盖到"真实" operator[]()返回索引和对元素的引用。但是,多个索引可能映射到该元素。如果我返回一个引用并允许它被更改,则会产生不希望的副作用,即更改其他索引的值。

如果我只是按值返回元素,则无法使用operator []分配值。

operator[]()内,我想知道一个操作是否计划更改元素的值,这样我就可以创建一个新元素,用索引做一些更奇特的舞蹈动作,并返回一个引用新元素。

这样的事情可能吗?如果没有,似乎我被迫按值返回,从而阻止用户使用[]修改值。

2 个答案:

答案 0 :(得分:3)

如果类有一个方法change_element并且每个人在更改时都调用此函数,那会很容易,不是吗?

template <typename T>
struct my_vec {
  T& change_element(int index, T new_value)
  { ... }
};

现在,我们的想法是从operator[]返回代理类,为您完成这项工作。

  // inside my_vec:
  struct proxy {
    my_vec *vec;
    int index;

    T& operator=(T o)
    { return vec->change_element(index, std::move(o)); }

    operator T() const { return (*const_cast<my_vec const*>(vec))[index]; }
  };

  proxy operator[](int i) { return proxy{this, i}; }
  T const& operator[](int i) const { ... }

没有开销,每个通用编译器都应该优化代理元素。

这个技巧甚至在vector<bool>的STL中使用。请查看此更完整的示例。

答案 1 :(得分:0)

您可以将具有转换运算符的类返回给类型和赋值运算符,该运算符通知向量元素需要更改。