Skip to content

Instantly share code, notes, and snippets.

@AndrewLipscomb
Created June 18, 2020 21:38
Show Gist options
  • Save AndrewLipscomb/3780552ed3cf243dcac64ef09abf91bf to your computer and use it in GitHub Desktop.
Save AndrewLipscomb/3780552ed3cf243dcac64ef09abf91bf to your computer and use it in GitHub Desktop.
Yet Another attempt at describing the SO question
#include "./templates_b.h"
#if defined(B_WITH_TAG)
template <>
auto do_foo(Tag<LocalTypeB>, LocalTypeB data)
{
return do_foo<bool>(data.the_val);
}
#endif
#include "./templates_b.h"
int main()
{
do_foo<double>(0.0);
do_foo<LocalTypeB>(LocalTypeB());
return 0;
}
#ifndef HEADER_B
#define HEADER_B
#include <type_traits>
#include "templates_top.h"
class LocalTypeB {
public:
bool the_val = false;
};
#if defined(B_WITH_TAG)
// This one works with tag dispatch
// But everything is still in the header
// template <typename T>
// auto do_foo(Tag<LocalTypeB>, T data)
// {
// return do_foo<bool>(data.the_val);
// }
// This one does not - but is what I want to achieve
template<>
auto do_foo(Tag<LocalTypeB>, LocalTypeB data);
#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
#endif // HEADER_B
#ifndef TOPHEADER
#define TOPHEADER
#include <type_traits>
#ifdef B_WITH_TAG
template <typename T> struct Tag{};
template <typename T>
auto do_foo(T data) -> decltype(do_foo(Tag<T>{}, data))
{
return do_foo(Tag<T>{}, data);
}
#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;
}
#endif //TOPHEADER
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment