c++ 14 中的“重载”下标赋值操作

"Overload" subscript-assignment operation in c++ 14

提问人:calad0i 提问时间:7/23/2023 最后编辑:calad0i 更新时间:7/27/2023 访问量:66

问:

问题:

我需要构造一个数组来存储一种类型的数据,但显示为另一种类型以节省内存。只有下标运算符 () 是必需的。[]

比如说,我有一个数组,显示为 fp32,但在内部存储 int8: 从 arr by 读取值时,重载返回 by value 的下标运算符即可。但是,当使用语法(如 )分配值时,由于我无法通过引用强制转换为,因此我无法修改内部值。arrarr[i]arr[i]=somevalueint8_tfloat32_t

我尝试过:

定义一个单独的方法将是一个简单的解决方案,但它需要修改与数组交互的所有其他代码,因此不受欢迎。set(unsigned int index, float32_t value)

我考虑使用模板数据类型进行内部存储,并重载其 operator=。但是,在这种情况下,无法确定 [] 运算符的返回类型,我无法继续操作。

法典

// 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.
C++ 模板 C++14

评论

2赞 Paul Sanders 7/23/2023
请发布您的代码。代码描述不能很好地沟通。

答:

5赞 Remy Lebeau 7/23/2023 #1

您需要做的是让数组类重载 返回代理对象,然后让代理重载用于写入和读取。然后,代理的操作员可以做任何您想做的事。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]; };
    }
};

在线演示

评论

0赞 Toby Speight 7/27/2023
可能值得注意的是,具有代理引用与标准容器语义不同,这会阻止某些标准算法使用它。这就是为什么有时使用起来有问题的原因。std::vector<bool>
0赞 Mooing Duck 7/28/2023
请注意,此代码是一个很好的开始,但您需要额外的复杂性才能正确。coliru.stacked-crooked.com/a/33ce1a39678fcf43const