与C ++中的自定义Vector类相关的问题。
template <typename T>
class Vector
{ ...
private:
T * mData; int mSize;
public:
proxy_element operator[](const size_type index) { return proxy_element(*this, index); }
const T& operator[](const size_type index) const { return mData[index]; }
};
template <typename T>
class proxy_element
{ ...
proxy_element(Vector<T>& m_parent, const size_type index);
proxy_elem& operator=(const T& rhs); // modifies data so invalidate on other memories
bool operator==(const proxy_elem& rhs) // only read, just copy data back.
...
}
使用proxy_element类的原因是为了区分和优化读写操作,考虑到矢量数据也可以驻留在GPU设备存储器中。因此,任何读取操作只需要复制最新数据(如果有),但读写/写入操作需要使器件存储器中的数据无效。
当元素类型是原始的时,这种设计很有效。但是对于更复杂的元素类型,有一个问题:
struct person{ int age; double salary; };
int main()
{
Vector<person> v1(10);
v[1].age = 10; // gives error as operator[] returns proxy_element for which "." operator has no meaning
}
AFAIK,“。”运算符不能在C ++中重载。一个显而易见的解决方案是不使用proxy_elem并且只返回常规引用(T&amp;),假设每次访问都是写访问,但由于显而易见的原因,这将是低效的。
还有其他任何工作让我“。”操作员工作,同时保留区分读写操作的能力?
答案 0 :(得分:1)
一种选择是使这些数据类型不可变(私有成员变量,由构造函数初始化,唯一的setter是类的赋值运算符)。这样,更改任何内容的唯一方法是分配给类的整个实例,该实例可以通过proxy_element引导。
答案 1 :(得分:0)
//if it's a class, inherit from it to get public members
template<class T>
class proxy_element : public T {
...
proxy_element(Vector<T>& m_parent, const size_type index);
proxy_elem& operator=(const T& rhs); // modifies data so invalidate on other memories
bool operator==(const proxy_elem& rhs) // only read, just copy data back.
...
};
//pretend to be a pointer
template<>
class proxy_element<T*> {
...
proxy_element(Vector<T>& m_parent, const size_type index);
proxy_elem& operator=(const T& rhs); // modifies data so invalidate on other memories
bool operator==(const proxy_elem& rhs) // only read, just copy data back.
...
};
//otherwise, pretend to be primitive
#define primitive_proxy(T) \
template<> class proxy_element {
...
proxy_element(Vector<T>& m_parent, const size_type index);
proxy_elem& operator=(const T& rhs); // modifies data so invalidate on other memories
bool operator==(const proxy_elem& rhs) // only read, just copy data back.
...
};
primitive_proxy(char)
primitive_proxy(unsigned char)
primitive_proxy(signed char) //this is distinct from char remember
primitive_proxy(short)
primitive_proxy(unsigned short)
primitive_proxy(int)
primitive_proxy(unsigned int)
primitive_proxy(long)
primitive_proxy(unsigned long)
primitive_proxy(long long)
primitive_proxy(unsigned long long)
primitive_proxy(char16_t) //if GCC
primitive_proxy(char32_t) //if GCC
primitive_proxy(wchar_t)
primitive_proxy(float)
primitive_proxy(double)
primitive_proxy(long double)