Skip to content

Instantly share code, notes, and snippets.

@npetrenko
Created March 29, 2019 09:49
Show Gist options
  • Save npetrenko/a68f890a89bfad40ad5cc9c3e58c4b98 to your computer and use it in GitHub Desktop.
Save npetrenko/a68f890a89bfad40ad5cc9c3e58c4b98 to your computer and use it in GitHub Desktop.
#include <type_traits>
#include <iostream>
// Template magic to test if class has .METHOD
#define ENABLEHASMETHOD(METHOD) \
template <class T__> \
struct Has_##METHOD { \
template <class U__, class = decltype(&(U__::METHOD))> \
static const std::true_type Tester(U__*); \
\
static const std::false_type Tester(...); \
\
static const bool value = decltype(Tester((T__*)0))::value; \
}
template <class T>
class Base {
public:
void Print() const {
// test if the method is overriden by child. If not, call base implementation
if constexpr (Has_PrintImpl<T>::value) {
static_cast<const T*>(this)->PrintImpl();
} else {
PrintImpl();
}
}
private:
ENABLEHASMETHOD(PrintImpl);
void PrintImpl() const {
std::cout << "This is a base printer!"
<< "\n";
}
};
class Derived : public Base<Derived> {
// enable Base to call PrintImpl
friend class Base<Derived>;
private:
void PrintImpl() const {
std::cout << "This is a derived printer"
<< "\n";
}
};
class NoPrinter : public Base<NoPrinter> {};
template <class T>
void TestPrint(const Base<T>& obj) {
obj.Print();
}
int main() {
Base<void> base;
Derived derived;
NoPrinter noprinter;
TestPrint(base);
TestPrint(derived);
TestPrint(noprinter);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment