C++ - 基于赋值方重载[]运算符

Jac*_*ink 10 c++ operator-overloading

我正在尝试用c ++编写动态数组模板

我目前正在重载[]运算符,我想根据它们使用的赋值方面实现不同的行为.

#include <iostream>
...

template <class T>
T dynamic_array<T>::operator[](int idx) {
    return this->array[idx];
}

template <class T>
T& dynamic_array<T>::operator[](int idx) {
    return this->array[idx];
}

using namespace std;
int main() {
    dynamic_array<int>* temp = new dynamic_array<int>();

    // Uses the T& type since we are explicitly 
    // trying to modify the stored object
    (*temp)[0] = 1;

    // Uses the T type since nothing in the array 
    // should be modified outside the array
    int& b = (*temp)[0]; 

    // For instance...
    b = 4;
    cout<<(*temp)[0]; // Should still be 1
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

出于显而易见的原因,我在尝试像这样重载时遇到编译器错误.

有没有正确的方法来做到这一点?

到目前为止,我的搜索还没有成功.我在重载[]运算符中看到的任何东西似乎都接受用户可以修改对象外部的存储项.

我已经实现了使用的方法(实例(int i),更新(int i,T obj))但是能够像常规数组一样使用这个类会很好.

Ker*_* SB 13

您不能仅在返回类型上重载.

提供常量和非常量访问器重载的标准方法是通过以下常量来区分this:

T       & get()       { return x; }
const T & get() const { return x; }  // or T get() const;
Run Code Online (Sandbox Code Playgroud)

对于常量版本,您可以返回const-reference或value,具体取决于T- const-reference可能更普遍有用.

(当然,代替get()你会写operator[](std::size_t i).我只想保持简短.)


我不认为,这达到100%,你脑子里想的是什么,但是那是因为你有你的推理错误:int b = foo()永远是任何一个参考,即使foo()回报(const或非const)引用,因为b声明是类型的int,不是int&.实际上,当你说时你实际上会调用非const版本int b = (*temp)[0];但实际上并不是问题.(要获得常数版本,你必须说int b = static_cast<const dynamic_array<int> &>(*temp)[0];(*static_cast<const dynamic_array<int> *>(temp))[0]- 但为什么要这么麻烦.)


Dre*_*all 8

Scott Meyers在其中一本Effective C++书中谈到了这一点.基本上诀窍是从索引运算符(operator[]()operator[]() const)返回临时的const或非const代理对象,然后重载该代理类的赋值和隐式转换运算符.像这样的东西:

template <class T>
class Array
{
  public:
    struct proxy {
      T& element;

      proxy(T& el) : element(el) {}

      operator const T& () const {
        return element; // For use on RHS of assignment
      }

      proxy& operator=(const T& rhs) {
        // For use on LHS of assignment
        // Add your logic here
      }
    };

    const proxy operator[](int i) const {
      return proxy(a[i]);
    }

    proxy operator[](int i) {
      return proxy(a[i]);
    }

  private:
     T* a;
};
Run Code Online (Sandbox Code Playgroud)

我可能有一些细节错误,但想法是推迟决定元素所在的赋值的哪一方,直到实际尝试分配给它.也就是说,您不知道在operator []调用时将要执行的操作,但是当您尝试分配给后续元素引用时,您肯定会这样做.