Skip to content

Instantly share code, notes, and snippets.

@valmat
Created March 27, 2018 19:10
Show Gist options
  • Save valmat/5c630e0c0a25f9087abc180a616ced4c to your computer and use it in GitHub Desktop.
Save valmat/5c630e0c0a25f9087abc180a616ced4c to your computer and use it in GitHub Desktop.
CRTP. Double static polymorphism
//
// CRTP. Double static polymorphism
//
// g++ -std=c++14 1.cpp && ./a.out
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;
// CT interface WordGetterBase
template<typename derived_t>
struct WordGetterBase
{
string getWord() const {
return static_cast<const derived_t*>(this)->getWord();
}
void printWord() const {
cout << getWord() << endl;
}
};
// Implemmentations WordGetterBase
struct WordGetterW1: public WordGetterBase<WordGetterW1>
{
string getWord() const {
return "Str1";
}
};
struct WordGetterW2: public WordGetterBase<WordGetterW2>
{
string getWord() const {
return "Str2";
}
};
//
// CT interface StrPrinterBase
//
template <template <typename WordGetter> class derived_t, typename WordGetter>
struct StrPrinterBase: public WordGetter
{
string getWord() const {
return static_cast<const WordGetter*>(this)->getWord();
}
void printStr() const {
//static_cast<const WordGetter* >(this)->printWord();
return static_cast< derived_t<WordGetter>* >(this)->printStr();
}
};
// Implemmentations StrPrinterBase
template <class WordGetter>
struct StrPrinter1: public StrPrinterBase<StrPrinter1, WordGetter>
{
using base = StrPrinterBase<StrPrinter1, WordGetter>;
void printStr() const {
cout << "[ " << base::getWord() << " ]" << endl;
}
};
template <class WordGetter>
struct StrPrinter2: public StrPrinterBase<StrPrinter1, WordGetter>
{
using base = StrPrinterBase<StrPrinter1, WordGetter>;
void printStr() const {
cout << "{ " << base::getWord() << " }" << endl;
}
};
int main()
{
WordGetterW1{}.printWord();
WordGetterW2{}.printWord();
cout << "~~~~~~~~~~~~" << endl;
StrPrinter1<WordGetterW1>{}.printStr();
StrPrinter2<WordGetterW2>{}.printStr();
StrPrinter2<WordGetterW1>{}.printStr();
//output:
//Str1
//Str2
//~~~~~~~~~~~~
//[ Str1 ]
//{ Str2 }
//{ Str1 }
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment