Created
June 6, 2024 17:38
-
-
Save DrkWithT/31872911be463445b8dbc72fa86b50ca to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
/* | |
Attempt at CRTP visitor sample | |
DrkWithT | |
*/ | |
/// Forward decls. of visitable objects | |
class OneBox; | |
class TwoBox; | |
/// Prints any XXBox's info | |
struct BoxVisitor | |
{ | |
BoxVisitor() = default; | |
void visitOneBox(const OneBox& one) const; | |
void visitTwoBox(const TwoBox& two) const; | |
}; | |
/// CRTP compile-time interface for an XXBox | |
template <typename Derived> | |
class Base | |
{ | |
private: | |
[[nodiscard]] Derived* getDerivedPtr() { return static_cast<Derived*>(this); } | |
public: | |
Base() = default; | |
void acceptVisitor(const BoxVisitor& printer) | |
{ | |
/// Here, I start double dispatch with the appropriate derived class's. The object is prompted to accept the printer. | |
getDerivedPtr()->acceptVisitor(printer); | |
} | |
}; | |
class OneBox : public Base<OneBox> | |
{ | |
private: | |
int a; | |
public: | |
constexpr OneBox(int a_) | |
: a {a_} {} | |
[[nodiscard]] int getA() const { return a; } | |
void acceptVisitor(const BoxVisitor& printer) | |
{ | |
// Here, the double dispatch is about to finish: the OneBox class knows by itself how to handle this visitation. | |
printer.visitOneBox(*this); | |
} | |
}; | |
class TwoBox : public Base<TwoBox> | |
{ | |
private: | |
int a; | |
int b; | |
public: | |
constexpr TwoBox(int a_, int b_) | |
: a {a_}, b {b_} {} | |
[[nodiscard]] int getA() const { return a; } | |
[[nodiscard]] int getB() const { return b; } | |
void acceptVisitor(const BoxVisitor& printer) | |
{ | |
printer.visitTwoBox(*this); | |
} | |
}; | |
/// Post-forward definitions of visitor's methods to help linker resolve dummy calls from forward decls. | |
void BoxVisitor::visitOneBox(const OneBox& one) const | |
{ | |
std::cout << "OneBox {" << one.getA() << '}' << '\n'; | |
} | |
void BoxVisitor::visitTwoBox(const TwoBox& two) const | |
{ | |
std::cout << "TwoBox {" << two.getA() << ',' << two.getB() << '}' << '\n'; | |
} | |
int main() | |
{ | |
// create visitable objects | |
OneBox single {42}; | |
TwoBox couple {20, 24}; | |
// create printing visitor | |
BoxVisitor box_display; | |
// test visit methods | |
box_display.visitOneBox(single); | |
box_display.visitTwoBox(couple); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment