Home > OS >  How conversion of pointer-to-base to void is better than pointer-to-derived to void conversion
How conversion of pointer-to-base to void is better than pointer-to-derived to void conversion

Time:07-07

[over.ics.rank]/4:

  • [..]
  • (4.3) If class B is derived directly or indirectly from class A, conversion of B* to A* is better than conversion of B* to void*, and conversion of A* to void* is better than conversion of B* to void*.

So if I have:

struct A {};
struct M : A {};
struct B : M {};

void f(A*);
void f(void*);

int main()
{
   B *bptr = new B();
   f(bptr);
}

The call f(bptr) would prefer the overload f(A*) over f(void*).

But in the second case: conversion of A* to void* is better than conversion of B* to void*. How this conversion can occur? Can you give me an example that triggers this case?


For some reasons I can't finds out a case or an example in which this case is applied. It seems like comparing two unrelated things to each other. But I encounter more in the bullet 4.4.

You can check the whole thing from cppreference para 4:

  1. If Mid is derived (directly or indirectly) from Base, and Derived is derived (directly or indirectly) from Mid
  • a) Derived* to Mid* is better than Derived* to Base*
  • b) Derived to Mid& or Mid&& is better than Derived to Base& or Base&&
  • c) Base::* to Mid::* is better than Base::* to Derived::*
  • d) Derived to Mid is better than Derived to Base
  • e) Mid* to Base* is better than Derived* to Base*
  • f) Mid to Base& or Base&& is better than Derived to Base& or Base&&
  • g) Mid::* to Derived::* is better than Base::* to Derived::*
  • h) Mid to Base is better than Derived to Base

CodePudding user response:

The situation where you have to compare different possible source types (A* vs B* in A* -> void* and B* -> void*) can only happen in the context of overload resolution for initialization by user-defined conversion, not in the context of overload resolution for a function call. See also the note at the end of [over.ics.rank]/4.

Here is an example where the quoted phrase is relevant:

struct A {};
struct B : A {};

struct C {
    operator A*();
    operator B*();
};

int main() {
    void* x = C{};
}

Here x is initialized by a conversion function chosen according to [over.match.conv] (see [dcl.init.general]/16.7). All conversion operators converting from C to any type which is convertible to void* by a standard conversion sequence are considered.

Then the best conversion function is chosen according to which of the standard conversion sequences following the conversion function is better (see [over.match.best.general]/2.2).

The phrase you quote tells us that A* -> void* is better than B* -> void*. So the conversion function which will be used here to initialize x is operator A*().

  • Related