Я понимаю реализацию решения и шаблон двойной отправки / посетителя, однако я не понимаю, что происходит во время компиляции и во время выполнения, когда нам нужен этот шаблон.
Например, этот код:
#include <iostream>
class A {
public:
};
class B : public A {
};
class F {
public:
virtual inline void operator()(const A&) const noexcept {
std::cout << "FxA" << std::endl;
}
virtual inline void operator()(const B&) const noexcept {
std::cout << "FxB" << std::endl;
}
};
class G : public F {
public:
virtual inline void operator()(const A&) const noexcept {
std::cout << "GxA" << std::endl;
}
virtual inline void operator()(const B&) const noexcept {
std::cout << "GxB" << std::endl;
}
};
void by_const_ref(const F& f, const A& a) {
f(a);
}
int main() {
by_const_ref(F(), A());
by_const_ref(F(), B());
by_const_ref(G(), A());
by_const_ref(G(), B());
return 0;
}
Без двойной отправки второй и четвертый вызов by_const_ref не преобразует B () в объект A.
Из этой статьи: https://en.wikipedia.org/wiki/Double_dispatch#Double_dispatch_in_C++ Я понимаю, что этовключает в себя искажение имени и время компиляции, а также разрешение vtable во время выполнения, но я не нашел, как именно.
Что касается обработки имени, я посмотрел на скомпилированный объект, но не нашел ничего особенного.
Для vtable я сбросил его с помощью g ++ -fdump-lang-class, и, похоже, там тоже не было много информации.
Отсюда мой запрос.Я хотел бы понять, что именно произошло, и, возможно, как проверить это поведение (используя такие инструменты, как nm, проверка vtable, машинный код?)