I came up with a solution with a template requirement -- please see below. It works fine with non-templated types (type A below), but not with templated types (type B below). I would appreciate it if someone could help me get it work with templated types too. Best, Irek *********************************************************** http://coliru.stacked-crooked.com/a/6219c292938b4067 Compiled with: g++ -std=c++2a -fconcepts main.cc -o main *********************************************************** #include <iostream> #include <type_traits> using namespace std; template <typename T> void foo(T &&t) { // The primary template implementation. cout << "Primary: " << __PRETTY_FUNCTION__ << endl; } struct A { }; template <typename T> void foo(T &&t) requires is_same_v<decay_t<T>, A> { // Overload for A. cout << "Overload for A: " << __PRETTY_FUNCTION__ << endl; } template <typename T> struct B { }; template <typename T> void foo(T &&t) requires is_same_v<decay_t<T>, B> { // Overload for B. cout << "Overload for B: " << __PRETTY_FUNCTION__ << endl; } int main() { foo(1); int i = 1; foo(i); const int ci = 1; foo(ci); foo(A()); A a; foo(a); const A ca; foo(ca); foo(B<int>()); B<int> b; foo(b); const B<int> cb; foo(cb); }