我是否可以使用用户定义的转换将原始指针访问替换为通过类访问

Can I use user-defined conversion to replace raw pointer access with access via classes?

本文关键字:访问 替换 指针 原始 可以使 是否 用户 定义 转换      更新时间:2023-10-16

我有一些旧代码,它按照以下行分配内存:

class IntArrayAllocator
{
    int* const m_array;
public:
    IntArrayAllocator(int n) : m_array(new int[n]) {}
    ~IntArrayAllocator() { delete[] m_array; }
    operator int*() const { return m_array; }
};
int main()
{
    IntArrayAllocator allocator(10);
    for(int i=0;i<10;++i) {
        allocator[i] = i;
    }
...

我想通过插入包装器而不是原始指针来开始使这段代码现代化,如下所示:

class IntArray
{
    int* const m_array;
public:
    IntArray(int* array) : m_array(array) {}
    int& operator[](int i) { return m_array[i]; }
    int operator[](int i) const { return m_array[i]; }
};
class IntArrayAllocator
{
...
    operator IntArray() const { return IntArray(m_array); } // replace previous operator int*
};

但随后用户定义的转换无法适用于该行

        allocator[i] = i;

错误no match for ‘operator[]’ (operand types are ‘IntArrayAllocator’ and ‘int’).我必须使用,例如,

        IntArray ia = allocator;
        ia[i] = i;

相反。

这个错误让我感到困惑,因为我认为我可以用用户定义的转换为我自己的类型来替换用户定义的转换为内置类型(在面向对象编程中,在模仿内置类型的类中插入感觉很自然(。我最接近理解为什么是这个答案:允许用户定义的转换导致调用其他类型的任意成员函数是没有意义的。这似乎也适用于运营商,尽管这最初感觉在这种情况下应该有效?(我知道很多人对这种事情的细节进行了非常深入的思考,并且很可能有充分的理由不允许这样做。

假设我已经在用户定义的转换中遇到了障碍,那么解决这个问题的好方法是什么?


编辑:我应该澄清一下,这个问题应该是我在尝试解决更大问题时遇到的问题的最小示例。例如,使用 std::vector 解决更大的问题是不合适的,因为,例如,我还需要能够切入分配器,给出一个仅引用部分分配内存的 int 数组对象。此外,分配的内存并不总是以相同的方式分配:它可能来自堆或堆栈,从某个第三方对象返回等。

请记住,name[...]name.operator[](...)没有什么不同(当name不是指针或数组类型时(。当您在name上调用成员函数时,类型转换不会在上发生。

因此,您想要的(能够在不直接添加此类成员的情况下将operator[]注入类型(是不可能的。 IntArrayAllocator必须具有自己的operator[]成员函数。它做什么取决于此,但它必须有一个。