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