英文:
"Overload" subscript-assignment operation in c++ 14
问题
问题:
我需要构建一个数组,它存储一种类型的数据,但在内存中以另一种类型的方式显示,以节省内存。只需要重载下标运算符([]
)。
例如,我有一个名为arr
的数组,它看起来像是fp32
,但实际上在内部存储的是int8
:
当通过arr[i]
从arr
中读取一个值时,通过返回值重载下标运算符就可以工作。然而,当使用类似arr[i]=somevalue
的语法来赋值时,由于我不能将int8_t
转换为float32_t
,因此无法修改内部值。
我尝试过的:
定义一个单独的方法set(unsigned int index, float32_t value)
将是一个简单的解决方案,但这将需要修改与数组交互的所有其他代码,因此不受欢迎。
我考虑使用模板数据类型进行内部存储,并重载其operator=
运算符。然而,在这种情况下,无法确定[]
运算符的返回类型,因此我无法进一步进行。
代码
// 虚拟转换函数
int8_t complex_downcast(double x) {
return x;
}
double complex_upcast(int8_t x) {
return x;
}
// 当前结构
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); // 设置为2.1,转换为int8并存储
std::cout << buf[0] << std::endl; // (double) 2.0000000
// 希望: 通过buf[index] = value替换buf.set(index, value),需要使用complex_downcast。
英文:
Issue:
I need to construct an array that stores one type of data but appears as another type for memory saving. Only the subscript operator ([]
) is required.
Say, I have an array arr
that appears as fp32 but stores int8 internally:
When reading a value from arr by arr[i]
, overloading the subscript operator that returns by value just works. However when assigning a value with syntax like arr[i]=somevalue
, as I cannot cast int8_t
to float32_t
with reference, I cannot modify the inside value.
What I tried:
Defining a separate method set(unsigned int index, float32_t value)
would be a simple solution, but it will require modifying all other code interacting with the array, thus not favored.
I considered using a template datatype for internal storing, and overloading its operator=. However, in this case the returned type of the [] operator cannot be determined and I cannot proceed further.
Code
// 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.
答案1
得分: 5
你需要做的是让数组类重载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) {
// 根据需要进行操作...
*elem = static_cast<T>(value);
return *this;
}
operator T() const {
// 根据需要进行操作...
return static_cast<T>(*elem);
}
};
proxy operator[](int i) {
return proxy{ &v[i] };
}
};
英文:
What you need to do is have the array class overload the operator[]
to return a proxy object, and then have the proxy overload operator=
for writing and operator T
for reading. Then your proxy's operators can do whatever you want.
Try something like this:
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]; };
}
};
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论