#include <type_traits>
#include <iostream>
template<class T>
struct foo_op
{
template<class Prefix, class Arg>
void operator()(Prefix&& p, Arg&& /* a */) const
{
p();
}
};
template <typename T>
auto
foo(T &&t)
{
auto op = foo_op<std::decay_t<T>>();
return op([funcname = __PRETTY_FUNCTION__]
{
std::cout << "Primary: " << funcname << std::endl;
}, std::forward<T>(t));
}
// then specialise
struct Bar {};
template<>
struct foo_op<Bar>
{
template<class Prefix, class Arg>
void operator()(Prefix&& /*p*/, Arg&& /*bar*/) const
{
std::cout << "It's a Bar\n";
}
};
int main()
{
foo(6); // default case
foo(Bar()); // bar case
}