我可以使用用户定义的转换将原始指针访问替换为通过 类 访问吗?
Can I use user-defined conversion to replace raw pointer access with access via classes?
我有一些旧代码按照以下行分配内存:
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;
相反。
这个错误让我很困惑,因为我认为我可以将用户定义的转换替换为内置类型,并将用户定义的转换替换为我自己的类型(插入 类模仿内置类型在面向对象编程中感觉很自然)。我最接近理解的原因是 this answer:允许用户定义的转换导致调用其他类型的任意成员函数是没有意义的。似乎这也适用于运营商,尽管最初感觉它应该适用于这种情况? (我知道很多人对这类事情的细节思考得非常深入,并且很可能有充分的理由不允许这样做。)
假设我遇到了用户定义转换的障碍,那么解决这个问题的好方法是什么?
编辑:我应该澄清一下,这个问题应该是我在尝试解决更大问题时遇到的问题的一个最小示例。例如,使用 std::vector
解决更大的问题是不合适的,因为,例如,我还需要能够切入分配器,给出一个仅引用部分的 int 数组对象分配的内存。此外,分配的内存不会总是以相同的方式分配:它可能来自堆或堆栈,从某些第 3 方对象等返回。
请记住 name[...]
与 name.operator[](...)
没有区别(当 name
不是指针或数组类型时)。当您在其上调用成员函数时,类型转换不会在 name
上发生。
所以你想要的(能够将 operator[]
注入类型而不直接添加这样的成员)是不可能的。 IntArrayAllocator
必须 有自己的 operator[]
成员函数。干什么就到那了,但必须要有一个。
我有一些旧代码按照以下行分配内存:
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;
相反。
这个错误让我很困惑,因为我认为我可以将用户定义的转换替换为内置类型,并将用户定义的转换替换为我自己的类型(插入 类模仿内置类型在面向对象编程中感觉很自然)。我最接近理解的原因是 this answer:允许用户定义的转换导致调用其他类型的任意成员函数是没有意义的。似乎这也适用于运营商,尽管最初感觉它应该适用于这种情况? (我知道很多人对这类事情的细节思考得非常深入,并且很可能有充分的理由不允许这样做。)
假设我遇到了用户定义转换的障碍,那么解决这个问题的好方法是什么?
编辑:我应该澄清一下,这个问题应该是我在尝试解决更大问题时遇到的问题的一个最小示例。例如,使用 std::vector
解决更大的问题是不合适的,因为,例如,我还需要能够切入分配器,给出一个仅引用部分的 int 数组对象分配的内存。此外,分配的内存不会总是以相同的方式分配:它可能来自堆或堆栈,从某些第 3 方对象等返回。
请记住 name[...]
与 name.operator[](...)
没有区别(当 name
不是指针或数组类型时)。当您在其上调用成员函数时,类型转换不会在 name
上发生。
所以你想要的(能够将 operator[]
注入类型而不直接添加这样的成员)是不可能的。 IntArrayAllocator
必须 有自己的 operator[]
成员函数。干什么就到那了,但必须要有一个。