1 namespace detail { 2 template <typename T> struct Quux {}; 3 } // namespace detail 4 5 using FuncPtr = detail::Quux<double> (*(*)(int))(float); 6 7 struct Foo { fooFoo8 template <typename T> void foo(T arg) const noexcept(true) {} 9 operator <<Foo10 template <int T> void operator<<(int) {} 11 returns_func_ptrFoo12 template <typename T> FuncPtr returns_func_ptr(detail::Quux<int> &&) const noexcept(false) { return nullptr; } 13 }; 14 15 namespace ns { foo(char const * str)16template <typename T> int foo(char const *str) noexcept(false) { return 0; } foo(T t)17template <typename T> int foo(T t) { return 1; } 18 returns_func_ptr(detail::Quux<int> &&)19template <typename T> FuncPtr returns_func_ptr(detail::Quux<int> &&) { return nullptr; } 20 } // namespace ns 21 bar()22int bar() { return 1; } 23 24 namespace { anon_bar()25int anon_bar() { return 1; } __anon310810fc0202null26auto anon_lambda = [] {}; 27 } // namespace 28 inlined_foo(const char * str)29__attribute__((always_inline)) int inlined_foo(const char *str) { 30 if (bool b = bar()) 31 return 1; 32 return 2; 33 } 34 main()35int main() { 36 ns::foo<decltype(bar)>(bar); 37 ns::foo<decltype(bar)>("bar"); 38 ns::foo(anon_lambda); 39 ns::foo(anon_bar); 40 ns::foo<decltype(&Foo::foo<int(int)>)>("method"); 41 ns::returns_func_ptr<int>(detail::Quux<int>{}); 42 Foo f; 43 f.foo(anon_bar); 44 f.operator<< <(2 > 1)>(0); 45 f.returns_func_ptr<int>(detail::Quux<int>{}); 46 inlined_foo("bar"); 47 return 0; 48 } 49