的解決方案是使用「代理」對象,將延遲實際操作:
#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
因爲您可能需要從非常量實例中讀取,所以無法使用該屬性,這就是您必須延遲操作的原因:分配發生在「訪問和編譯器之後」之後告訴你訪問是否將被用作分配目標。
因此,這個想法是,在訪問時,您只需存儲已請求的索引,並等待知道是正在進行讀取還是寫入操作。通過提供從代理到T
的隱式轉換運算符,您知道何時發生讀取操作,通過向T
中的代理提供並分配運算符,您知道何時發生寫入操作。
您可能想要查找*代理對象*,這通常用於區分讀取和寫入。 – templatetypedef
請參見Scott Meyers [更有效的C++]中的第30項「代理類」(http://www.amazon.com/More-Effective-Improve-Programs-ebook/dp/B004VSMDNY/ref=la_B004BBEYYW_1_2?s=books&ie= UTF8&qid = 1381129998&sr = 1-2)進行廣泛的討論,包括代理類可以爲您提供的令人驚訝的缺陷(與用戶定義的轉換有關)。該材料是[強制性閱讀](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)。 – TemplateRex