The idiomatic way is to delegate the work to an auxiliary function object in the detail namespace, which you can partially specialize for the case when T matches U (or for any other compile-time pattern that you can use in class templates).
namespace detail { template<typename T, typename U> struct foo { int operator()() const { return 0; } }; template<typename T> struct foo<T, T> { int operator()() const { return 42; } }; }
For functions that also have output arguments (for example, a Foo(T x, U y) ), this combines the ability of an argument to subtract function templates and the ability to specialize class templates, without each user being wiser (well, you you need an agreement that they do not call anything from namespace detail directly)
source share