I understand the implementation of the solution and the double dispatch/visitor pattern, however I don't understand what happens at compile time and run-time that we need this pattern.
For example this code:
#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;
}
Without double dispatch the second and fourth call to by_const_ref will not resolve B() into a A object.
From this article: https://en.wikipedia.org/wiki/Double_dispatch#Double_dispatch_in_C++ I understand that it involves name mangling and compile time and vtable resolution at run-time, but I didn't find how exactly.
For the name-mangling part I looked at the compiled object but didn't find anything special.
For the vtable I dumped it with g++ -fdump-lang-class and it didn't looked like there were much information there too.
Hence my request. I'd like to understand what exactly happened and maybe how to check this behavior (using tools like nm, checking the vtable, the machine code ?)