Last active
March 20, 2018 13:47
-
-
Save artivis/e53c3d67ef5100da909dc99b4a842995 to your computer and use it in GitHub Desktop.
Fun with CRTP
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
// Example program | |
#include <iostream> | |
#include <string> | |
template<class, typename T, class...> struct has_speak_m_impl : std::false_type {}; | |
template<typename T, class... Args> struct has_speak_m_impl<decltype( std::declval<T>().speak(std::declval<Args...>()) ), T> : std::true_type {}; | |
template<typename T, class... Args> struct has_speak_m : has_speak_m_impl<void, T, Args...> {}; | |
template <typename Derived> | |
struct BaseInterface | |
{ | |
template <typename... Ts> | |
typename std::enable_if<has_speak_m<Derived, Ts...>::value>::type | |
speak(Ts&&... val) | |
{ | |
//calling Derived speak | |
derived().speak(std::forward<Ts>(val)...); | |
} | |
template <typename... Ts> | |
typename std::enable_if<!has_speak_m<Derived, Ts...>::value>::type | |
speak(Ts&&...) | |
{ | |
std::cout << "default speak.\n"; | |
} | |
protected: | |
constexpr Derived& derived() { return static_cast< Derived& >(*this); } | |
}; | |
struct DerivedA : BaseInterface<DerivedA> | |
{ | |
void speak(const int val) const { std::cout << "DerivedA speak : " << val << "\n"; } | |
}; | |
struct DerivedB : BaseInterface<DerivedB> | |
{ | |
template <typename T> int speak(const T& val) const { std::cout << "DerivedB speak : " << val << "\n"; return 0; } | |
}; | |
struct DerivedC : BaseInterface<DerivedC> { }; | |
struct DerivedD : BaseInterface<DerivedD> { int speak_impl; }; | |
struct DerivedE : BaseInterface<DerivedE> { using speak_impl = int; }; | |
int main() | |
{ | |
DerivedA derived_a; | |
DerivedB derived_b; | |
DerivedC derived_c; | |
DerivedD derived_d; | |
DerivedE derived_e; | |
derived_a.speak(0); | |
derived_b.speak("1"); | |
derived_c.speak(3,3); | |
derived_d.speak(3,3); | |
derived_e.speak(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment