1 | // RUN: %clang_cc1 -std=c++1z -verify %s |
2 | |
3 | // Test that we cope with failure to expand a pack. |
4 | template<typename ...T> struct Unexpanded : T... { |
5 | using T::f; // expected-error {{unexpanded}} |
6 | using typename T::type; // expected-error {{unexpanded}} |
7 | template<typename ...U> void g(U ...u) { f(u...); } // expected-error {{undeclared identifier 'f'}} |
8 | void h() { |
9 | Unexpanded<type...> *p; // expected-error {{undeclared identifier 'type'}} |
10 | } |
11 | }; |
12 | void test_Unexpanded() { |
13 | struct A { void f(); }; // expected-note {{must qualify}} |
14 | struct B { void f(int); }; // expected-note {{must qualify}} |
15 | Unexpanded<A, B>().g(0); // expected-note {{instantiation of}} |
16 | } |
17 | |
18 | // Test using non-type members from pack of base classes. |
19 | template<typename ...T> struct A : T... { // expected-note 2{{candidate}} |
20 | using T::T ...; // expected-note 2{{inherited here}} |
21 | using T::operator() ...; |
22 | using T::operator T* ...; |
23 | using T::h ...; |
24 | |
25 | void f(int n) { h(n); } // expected-error {{ambiguous}} |
26 | void f(int n, int m) { h(n, m); } // expected-error {{member using declaration 'h' instantiates to an empty pack}} |
27 | void g(int n) { (*this)(n); } // expected-error {{ambiguous}} |
28 | void g(int n, int m) { (*this)(n, m); } // expected-error {{does not provide a call operator}} |
29 | }; |
30 | |
31 | namespace test_A { |
32 | struct X { |
33 | X(); |
34 | X(int); // expected-note {{candidate}} |
35 | void operator()(int); // expected-note 2{{candidate}} |
36 | operator X *(); |
37 | void h(int); // expected-note {{candidate}} |
38 | }; |
39 | struct Y { |
40 | Y(); |
41 | Y(int, int); |
42 | void operator()(int, int); |
43 | operator Y *(); |
44 | void h(int, int); // expected-note {{not viable}} |
45 | }; |
46 | struct Z { |
47 | Z(); |
48 | Z(int); // expected-note {{candidate}} |
49 | void operator()(int); // expected-note 2{{candidate}} |
50 | operator Z *(); |
51 | void h(int); // expected-note {{candidate}} |
52 | }; |
53 | |
54 | void f() { |
55 | A<> a; |
56 | a.f(0, 0); // expected-note {{instantiation of}} |
57 | a.g(0, 0); // expected-note {{instantiation of}} |
58 | |
59 | A<X, Y> axy(0); |
60 | A<X, Y>(0, 0); |
61 | axy.f(0); |
62 | axy.f(0, 0); |
63 | axy.g(0); |
64 | axy.g(0, 0); |
65 | axy(0); |
66 | axy(0, 0); |
67 | |
68 | A<X, Y, Z>(0); // expected-error {{ambiguous}} |
69 | A<X, Y, Z> axyz(0, 0); |
70 | axyz.f(0); // expected-note {{instantiation of}} |
71 | axyz.f(0, 0); |
72 | axyz.g(0); // expected-note {{instantiation of}} |
73 | axyz.g(0, 0); |
74 | axyz(0); // expected-error {{ambiguous}} |
75 | axyz(0, 0); |
76 | |
77 | X *x; |
78 | x = a; // expected-error {{incompatible}} |
79 | x = axy; |
80 | x = axyz; |
81 | x = a.operator X*(); // expected-error {{no member}} |
82 | x = axy.operator X*(); |
83 | x = axyz.operator X*(); |
84 | |
85 | Z *z; |
86 | z = axyz; |
87 | z = axyz.operator Z*(); |
88 | } |
89 | } |
90 | |
91 | // Test using pack of non-type members from single base class. |
92 | template<typename X, typename Y, typename ...T> struct B : X, Y { |
93 | using X::operator T* ...; |
94 | }; |
95 | |
96 | namespace test_B { |
97 | struct X { operator int*(); operator float*(); operator char*(); }; // expected-note {{candidate}} |
98 | struct Y { operator int*(); operator float*(); operator char*(); }; // expected-note {{candidate}} |
99 | B<X, Y, int, float> bif; |
100 | int *pi = bif; |
101 | float *pf = bif; |
102 | char *pc = bif; // expected-error {{ambiguous}} |
103 | } |
104 | |
105 | // Test using type member from pack of base classes. |
106 | template<typename ...T> struct C : T... { |
107 | using typename T::type ...; // expected-error {{target of using declaration conflicts}} |
108 | void f() { type value; } // expected-error {{member using declaration 'type' instantiates to an empty pack}} |
109 | }; |
110 | |
111 | namespace test_C { |
112 | struct X { typedef int type; }; |
113 | struct Y { typedef int type; }; // expected-note {{conflicting}} |
114 | struct Z { typedef float type; }; // expected-note {{target}} |
115 | |
116 | void f() { |
117 | C<> c; |
118 | c.f(); // expected-note {{instantiation of}} |
119 | |
120 | C<X, Y> cxy; |
121 | cxy.f(); |
122 | |
123 | C<X, Y, Z> cxyz; // expected-note {{instantiation of}} |
124 | cxyz.f(); |
125 | } |
126 | } |
127 | |
128 | // Test using pack of non-types at block scope. |
129 | template<typename ...T> int fn1() { |
130 | using T::e ...; // expected-error 2{{class member}} expected-note 2{{instead}} |
131 | // expected-error@-1 2{{produces multiple values}} |
132 | return e; // expected-error {{using declaration 'e' instantiates to an empty pack}} |
133 | } |
134 | |
135 | namespace test_fn1 { |
136 | struct X { static int e; }; |
137 | struct Y { typedef int e; }; |
138 | inline namespace P { enum E { e }; } |
139 | inline namespace Q { enum F { e }; } |
140 | void f() { |
141 | fn1<>(); // expected-note {{instantiation of}} |
142 | fn1<X>(); // expected-note {{instantiation of}} |
143 | fn1<Y>(); // expected-note {{instantiation of}} |
144 | fn1<E>(); |
145 | fn1<E, F>(); // expected-note {{instantiation of}} |
146 | fn1<E, X>(); // expected-note {{instantiation of}} |
147 | } |
148 | } |
149 | |
150 | // Test using pack of types at block scope. |
151 | template<typename ...T> void fn2() { |
152 | // This cannot ever be valid: in order for T::type to be a type, T must be a |
153 | // class, and a class member cannot be named by a block-scope using declaration. |
154 | using typename T::type ...; // expected-error {{class member}} |
155 | type x; // expected-error {{unknown type name 'type'}} |
156 | } |
157 | |
158 | // Test partial substitution into class-scope pack. |
159 | template<typename ...T> auto lambda1() { |
160 | return [](auto x) { |
161 | struct A : T::template X<decltype(x)>... { // expected-note 1+{{instantiation of}} |
162 | using T::template X<decltype(x)>::f ...; |
163 | using typename T::template X<decltype(x)>::type ...; |
164 | void g(int n) { f(n); } // expected-error {{empty pack}} expected-error {{expected 2, have 1}} expected-error {{ambiguous}} |
165 | void h() { type value; } // expected-error {{empty pack}} |
166 | }; |
167 | return A(); |
168 | }; |
169 | } |
170 | |
171 | namespace test_lambda1 { |
172 | struct A { |
173 | template<typename> struct X { |
174 | void f(int); // expected-note {{candidate}} |
175 | using type = int; |
176 | }; |
177 | }; |
178 | struct B { |
179 | template<typename> struct X { |
180 | void f(int, int); // expected-note {{declared here}} expected-note {{not viable}} |
181 | using type = int; |
182 | }; |
183 | }; |
184 | struct C { |
185 | template<typename> struct X { |
186 | void f(int); // expected-note {{candidate}} |
187 | void f(int, int); // expected-note {{not viable}} |
188 | using type = int; |
189 | }; |
190 | }; |
191 | |
192 | void f() { |
193 | lambda1<>() // expected-note 2{{instantiation of}} |
194 | (0) |
195 | // FIXME: This is poor error recovery |
196 | .g(0); // expected-error {{no member named 'g'}} |
197 | lambda1<A>() |
198 | (0) |
199 | .g(0); |
200 | lambda1<B>() |
201 | (0) // expected-note {{instantiation of}} |
202 | .g(0); |
203 | lambda1<A, B, C>() |
204 | (0) // expected-note {{instantiation of}} |
205 | .g(0); |
206 | } |
207 | } |
208 | |
209 | namespace p0195r2_example { |
210 | template<typename ...Ts> |
211 | struct Overloader : Ts... { |
212 | using Ts::operator() ...; |
213 | }; |
214 | |
215 | template<typename ...Ts> |
216 | constexpr auto make_overloader(Ts &&...ts) { |
217 | return Overloader<Ts...>{static_cast<Ts&&>(ts)...}; |
218 | } |
219 | |
220 | void test() { |
221 | auto o = make_overloader( |
222 | [&](int &r) -> int & { return r; }, // expected-note {{candidate function}} |
223 | [&](float &r) -> float & { return r; } // expected-note {{candidate function}} |
224 | ); |
225 | int a; float f; double d; |
226 | int &ra = o(a); |
227 | float &rf = o(f); |
228 | double &rd = o(d); // expected-error {{no matching function}} |
229 | } |
230 | } |
231 | |