隐式转换为指针

Implicit conversion to pointer

我有这段代码:

struct A
{
    operator int*() { return nullptr; }
};
int main()
{
    A x;
    x[42] = 42;
    int z = x[42];
}

令我惊讶的是,编译了以下内容。隐式转换发生并有条件地将 A 转换为 int* 并访问指针给定的内存(为了简单起见,我返回 nullptr )。正如 reference 所说:

每当在不接受该类型但接受其他类型 T2 的上下文中使用某种类型 T1 的表达式时,就会执行隐式转换;特别是:

那么,为什么下面的方法不起作用?

struct A
{
    int operator[](int)
    {
        return 42;    
    }
};

struct B
{
    operator A()
    {
        return A();
    }
};

int main()
{
    B x;
    int z = x[42];
    x[42] = 42;
}

编译器说:error: no match for 'operator[]' (operand types are 'B' and 'int')。我错过了什么?

在调用成员函数之前不应用这些自动转换。下面是一个很好的例子

struct A {
    bool operator<(int) const {
        return true;
    }
};

bool operator>(const A &, int) {
    return false;
}

struct B {
    operator A() {
        return A();
    }
};

int main() {
    B b;
    auto z1 = b > 5;  // Works; calls operator<(B::operator A(), int)
    auto z2 = b < 5;  // Compile error; tries to call B::operator(int) which does not exist
}

你看,我们定义 <> 非常相似,但是 < 作为成员而 > 作为自由函数。对于自由函数,隐式转换已经完成,对于成员函数则没有。

将这个带到你的例子中 int * 不是一个对象,因此,它不能有成员函数。所以 operator[] for int * 基本上是一个自由函数(这不完全正确,它在语言中更根深蒂固。但我认为这是一个有用的思考模型)。因此,我们可以调用 operator[](A::operator int*(), int).

您无法为对象类型重现此行为,因为 operator[] 无法定义为自由函数(语言就是这样)。