cal*_*d0i 0 c++ templates c++14
我需要构造一个数组来存储一种类型的数据,但显示为另一种类型以节省内存。[]仅需要下标运算符 ( )。
假设我有一个arr显示为 fp32 但内部存储 int8 的数组:当从 arr by 读取值时arr[i],重载按值返回的下标运算符就可以了。但是,当使用类似 的语法分配值时arr[i]=somevalue,由于我无法通过引用int8_t进行转换float32_t,因此无法修改内部值。
定义一个单独的方法set(unsigned int index, float32_t value)将是一个简单的解决方案,但它需要修改与数组交互的所有其他代码,因此不受欢迎。
我考虑使用模板数据类型进行内部存储,并重载其运算符=。但是,在这种情况下,无法确定 [] 运算符的返回类型,并且我无法继续进行。
// dummy cast functions
int8_t complex_downcast(double x) {
return x;
}
double complex_upcast(int8_t x) {
return x;
}
// current structure
template <typename T, unsigned int N> struct buffer {
int8_t v[N];
T get(int i) const {
return complex_upcast(v[i]);
}
T operator[](int i) const {
return get(i);
}
void set(int i, T v) {
this->v[i] = complex_downcast(v);
}
};
buffer<double, 1> buf;
buf.set(0, 2.1); // Sets 2.1, cast to int8 and stored
std::cout << buf[0] << std::endl; // (double) 2.0000000
// Want: replace buf.set(index, value) by buf[index] = value, where complex_downcast is required.
Run Code Online (Sandbox Code Playgroud)
您需要做的是让数组类重载operator[]以返回代理对象,然后让代理重载operator=用于写入和operator T读取。然后你的代理操作员就可以做任何你想做的事。
尝试这样的事情:
template <typename T, unsigned int N> struct buffer {
int8_t v[N];
struct proxy {
int8_t *elem;
proxy& operator=(T value) {
// whatever you need...
*elem = static_cast<T>(value);
return *this;
}
operator T() const {
// whatever you need...
return static_cast<T>(*elem);
}
};
proxy operator[](int i) {
return proxy{ &v[i]; };
}
};
Run Code Online (Sandbox Code Playgroud)