【发布时间】:2022-07-06 23:12:17
【问题描述】:
- [..]
- (4.3) 如果 B 类直接或间接从 A 类派生,则 B* 到 A* 的转换优于 B* 到 void* 的转换,A* 到 void* 的转换优于 B 的转换* 作废*。
如果我有:
struct A {};
struct M : A {};
struct B : M {};
void f(A*);
void f(void*);
int main()
{
B *bptr = new B();
f(bptr);
}
调用f(bptr) 更喜欢重载f(A*) 而不是f(void*)。
但在第二种情况下:将 A* 转换为 void* 优于将 B* 转换为 void*。这种转换是如何发生的?你能给我一个触发这个案例的例子吗?
由于某些原因,我找不到适用此案例的案例或示例。似乎将两个不相关的事物相互比较。但我在子弹4.4遇到更多。
你可以从cppreference第4段检查整个事情:
- 如果 Mid 是(直接或间接)从 Base 派生的,并且 Derived 从 Mid 派生(直接或间接)
- a) Derived* to Mid* 优于 Derived* to Base*
- b) 派生到 Mid& 或 Mid&& 优于 Derived to Base& 或 Base&&
- c) Base::* to Mid::* 优于 Base::* to Derived::*
- d) Derived to Mid 优于 Derived to Base
- e) Mid* to Base* 优于 Derived* to Base*
- f) Mid to Base& 或 Base&& 优于 Derived to Base& 或 Base&&
- g) Mid::* 到 Derived::* 优于 Base::* 到 Derived::*
- h) Mid to Base 优于 Derived to Base
我要问的是从e)点开始
所以如果Mid 是M 和Base 是B 和Derived 是D,我有以下类:
struct B { int mem{}; };
struct iM : B {};
struct M : iM {}; // M is derived indirectly from B
struct jM : M {};
struct D : jM {}; // D is derived indirectly from M and from B.
从 e 点:M* 到 B* 优于 D* 到 B*。这怎么会发生?
【问题讨论】:
-
也许如果你只有
void*过载,它会去B*->A*->void*?这对于B*和A*指向不同位置的深层继承可能很重要。 -
或多个参数:
void f(A*, void*); void f(void*, B*); A *aptr = new A(); f(aptr, bptr);会选择f(void*, B*)? -
void* 那是什么?开个玩笑,只是好奇,C++ 中的 void* 有什么用? (除非它是为了与一些遗留 api 通信)。还是有一点语言的修饰?
-
@GoswinvonBrederlow 根据标准的重载解析从不考虑不同位置的参数之间的序列排名。这通常会使似乎具有明显更可取的重载的调用变得模棱两可,这就是为什么一些编译器为这些情况实现了一些合理的解决方案,但它们不符合标准。
标签: c++ class overload-resolution