Created
June 18, 2020 12:53
-
-
Save AndrewLipscomb/21f11d853cbb5a5f2dca2ccfe4cd122a to your computer and use it in GitHub Desktop.
Revisions
-
AndrewLipscomb created this gist
Jun 18, 2020 .There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,9 @@ #include "./templates_a.h" // Compile `gcc main_a.cpp` int main() { do_foo<LocalTypeA>(LocalTypeA()); return 0; } 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,33 @@ #include "./templates_b.h" #ifdef B_WITH_HELPER // Compile gcc main_b.cpp -DB_WITH_HELPER // This would normally be in its own impl - in the main for simplicity int do_foo(LocalTypeB bb) { // This is where I'd rather the detailed business logic be return 9001; } #endif #ifdef B_IN_IMPL // Compile gcc main_b.cpp -DB_IN_IMPL // This would normally be in its own impl - in the main for simplicity int do_foo(LocalTypeB bb) { return 9001; } #endif int main() { do_foo<double>(0.0); do_foo<LocalTypeB>(LocalTypeB()); return 0; } 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,15 @@ #include <type_traits> class LocalTypeA { }; template<typename T> std::enable_if_t<std::is_same<T, LocalTypeA>::value, int> do_foo(T bb) { // Some detailed business logic // specific to LocalTypeA and LocalTypeB that ideally isn't in a header // Key goal here is to be able to move this logic out of the header without // - more helper functions (ie: more header boilerplate per class) - ideally we just declare a template specialisation in the header // - exposing the lower classes to top level headers via fwd declaration // - breaking the resolution for funcs which _have_ to be in the header - like the std::is_fundamental one in templates_top.h return 2; } 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,37 @@ #include <type_traits> #include "templates_top.h" class LocalTypeB { public: bool the_val = false; }; #ifdef B_WITH_HELPER template <typename T> struct helper< T, std::enable_if_t< std::is_same<T, LocalTypeB>::value > > : std::true_type {}; template<> int do_foo(LocalTypeB bb); #endif #ifdef B_IN_IMPL template<> int do_foo(LocalTypeB bb); #else template<typename T> std::enable_if_t<std::is_same<T, LocalTypeB>::value, int> do_foo(T bb) { // Some detailed business logic here // specific to LocalTypeB that ideally isn't in a header // Also - we need to invoke generic impl of the same template further up return do_foo<bool>(bb.the_val); } #endif 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,33 @@ #include <type_traits> #ifdef B_WITH_HELPER template<typename T, typename = void> struct helper : std::false_type {}; template<typename T> std::enable_if_t<helper<T>::value, int> do_foo(T bb) { static_assert(std::is_same<T, void>::value && false, "Never do this"); } #endif #ifdef B_IN_IMPL template<typename T> int do_foo(T bb) { static_assert(std::is_same<T, void>::value && false, "Never do this"); } #endif template<typename T> std::enable_if_t<std::is_fundamental<T>::value, int> do_foo(T bb) { // Some generic business logic for all fundamental types here // OK to live in a header, not much we can do here return 0; }