Created
June 18, 2020 12:53
-
-
Save AndrewLipscomb/21f11d853cbb5a5f2dca2ccfe4cd122a to your computer and use it in GitHub Desktop.
Better C++ SE question
This file contains 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 "./templates_a.h" | |
// Compile `gcc main_a.cpp` | |
int main() | |
{ | |
do_foo<LocalTypeA>(LocalTypeA()); | |
return 0; | |
} |
This file contains 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 "./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 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 <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 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 <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 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 <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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment