namespace detail { template struct Quux {}; } // namespace detail using FuncPtr = detail::Quux (*(*)(int))(float); struct Foo { template void foo(T arg) const noexcept(true) {} template void operator<<(int) {} template FuncPtr returns_func_ptr(detail::Quux &&) const noexcept(false) { return nullptr; } }; namespace ns { template int foo(char const *str) noexcept(false) { return 0; } template int foo(T t) { return 1; } template FuncPtr returns_func_ptr(detail::Quux &&) { return nullptr; } } // namespace ns int bar() { return 1; } namespace { int anon_bar() { return 1; } auto anon_lambda = [] {}; } // namespace int main() { ns::foo(bar); ns::foo("bar"); ns::foo(anon_lambda); ns::foo(anon_bar); ns::foo)>("method"); ns::returns_func_ptr(detail::Quux{}); Foo f; f.foo(anon_bar); f.operator<< <(2 > 1)>(0); f.returns_func_ptr(detail::Quux{}); return 0; }