隐式转换为指针
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 的表达式时,就会执行隐式转换;特别是:
- 当表达式用作期望 T2 的运算符的操作数时
那么,为什么下面的方法不起作用?
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[]
无法定义为自由函数(语言就是这样)。
我有这段代码:
struct A
{
operator int*() { return nullptr; }
};
int main()
{
A x;
x[42] = 42;
int z = x[42];
}
令我惊讶的是,编译了以下内容。隐式转换发生并有条件地将 A
转换为 int*
并访问指针给定的内存(为了简单起见,我返回 nullptr
)。正如 reference 所说:
每当在不接受该类型但接受其他类型 T2 的上下文中使用某种类型 T1 的表达式时,就会执行隐式转换;特别是:
- 当表达式用作期望 T2 的运算符的操作数时
那么,为什么下面的方法不起作用?
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[]
无法定义为自由函数(语言就是这样)。