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