解决方案是使用会延迟实际操作的“代理”对象:
#include <vector>
#include <iostream>
template<typename T>
struct MyArray {
std::vector<T> data;
MyArray(int size) : data(size) {}
struct Deref {
MyArray& a;
int index;
Deref(MyArray& a, int index) : a(a), index(index) {}
operator T() {
std::cout << "reading\n"; return a.data[index];
}
T& operator=(const T& other) {
std::cout << "writing\n"; return a.data[index] = other;
}
};
Deref operator[](int index) {
return Deref(*this, index);
}
};
int main(int argc, const char *argv[]) {
MyArray<int> foo(3);
foo[1] = 42;
std::cout << "Value is " << foo[1] << "\n";
return 0;
}
const
不能使用简单-ness,因为您可能需要从非常量实例中读取,这就是您必须延迟操作的原因:赋值发生在访问“之后”并且编译器不会告诉您访问是否稍后将用作分配或不分配的目标。
因此,这个想法是,在访问时,您只需存储已请求的索引并等待知道是否正在发生读取或写入操作。通过向代理提供隐式转换运算符,T
您知道何时发生读取操作,通过向代理提供赋值运算符,T
您知道何时发生写入。