1 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
2 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++1z
3
4 // Template argument deduction with template template parameters.
5 template<typename T, template<T> class A>
6 struct X0 {
7 static const unsigned value = 0;
8 };
9
10 template<template<int> class A>
11 struct X0<int, A> {
12 static const unsigned value = 1;
13 };
14
15 template<int> struct X0i;
16 template<long> struct X0l;
17 int array_x0a[X0<long, X0l>::value == 0? 1 : -1];
18 int array_x0b[X0<int, X0i>::value == 1? 1 : -1];
19
20 template<typename T, typename U>
21 struct is_same {
22 static const bool value = false;
23 };
24
25 template<typename T>
26 struct is_same<T, T> {
27 static const bool value = true;
28 };
29
30 template<typename T> struct allocator { };
31 template<typename T, typename Alloc = allocator<T> > struct vector {};
32
33 // Fun with meta-lambdas!
34 struct _1 {};
35 struct _2 {};
36
37 // Replaces all occurrences of _1 with Arg1 and _2 with Arg2 in T.
38 template<typename T, typename Arg1, typename Arg2>
39 struct Replace {
40 typedef T type;
41 };
42
43 // Replacement of the whole type.
44 template<typename Arg1, typename Arg2>
45 struct Replace<_1, Arg1, Arg2> {
46 typedef Arg1 type;
47 };
48
49 template<typename Arg1, typename Arg2>
50 struct Replace<_2, Arg1, Arg2> {
51 typedef Arg2 type;
52 };
53
54 // Replacement through cv-qualifiers
55 template<typename T, typename Arg1, typename Arg2>
56 struct Replace<const T, Arg1, Arg2> {
57 typedef typename Replace<T, Arg1, Arg2>::type const type;
58 };
59
60 // Replacement of templates
61 template<template<typename> class TT, typename T1, typename Arg1, typename Arg2>
62 struct Replace<TT<T1>, Arg1, Arg2> {
63 typedef TT<typename Replace<T1, Arg1, Arg2>::type> type;
64 };
65
66 template<template<typename, typename> class TT, typename T1, typename T2,
67 typename Arg1, typename Arg2>
68 struct Replace<TT<T1, T2>, Arg1, Arg2> {
69 typedef TT<typename Replace<T1, Arg1, Arg2>::type,
70 typename Replace<T2, Arg1, Arg2>::type> type;
71 };
72
73 // Just for kicks...
74 template<template<typename, typename> class TT, typename T1,
75 typename Arg1, typename Arg2>
76 struct Replace<TT<T1, _2>, Arg1, Arg2> {
77 typedef TT<typename Replace<T1, Arg1, Arg2>::type, Arg2> type;
78 };
79
80 int array0[is_same<Replace<_1, int, float>::type, int>::value? 1 : -1];
81 int array1[is_same<Replace<const _1, int, float>::type, const int>::value? 1 : -1];
82 int array2[is_same<Replace<vector<_1>, int, float>::type, vector<int> >::value? 1 : -1];
83 int array3[is_same<Replace<vector<const _1>, int, float>::type, vector<const int> >::value? 1 : -1];
84 int array4[is_same<Replace<vector<int, _2>, double, float>::type, vector<int, float> >::value? 1 : -1];
85
86 // PR5911
87 template <typename T, int N> void f(const T (&a)[N]);
88 int iarr[] = { 1 };
test_PR5911()89 void test_PR5911() { f(iarr); }
90
91 // Must not examine base classes of incomplete type during template argument
92 // deduction.
93 namespace PR6257 {
94 template <typename T> struct X {
95 template <typename U> X(const X<U>& u);
96 };
97 struct A;
98 void f(A& a);
99 void f(const X<A>& a);
test(A & a)100 void test(A& a) { (void)f(a); }
101 }
102
103 // PR7463
104 namespace PR7463 {
105 const int f ();
106 template <typename T_> void g (T_&); // expected-note{{T_ = int}}
h(void)107 void h (void) { g(f()); } // expected-error{{no matching function for call}}
108 }
109
110 namespace test0 {
111 template <class T> void make(const T *(*fn)()); // expected-note {{candidate template ignored: cannot deduce a type for 'T' that would make 'const T' equal 'char'}}
112 char *char_maker();
test()113 void test() {
114 make(char_maker); // expected-error {{no matching function for call to 'make'}}
115 }
116 }
117
118 namespace test1 {
119 template<typename T> void foo(const T a[3][3]);
test()120 void test() {
121 int a[3][3];
122 foo(a);
123 }
124 }
125
126 // PR7708
127 namespace test2 {
128 template<typename T> struct Const { typedef void const type; };
129
130 template<typename T> void f(T, typename Const<T>::type*);
131 template<typename T> void f(T, void const *);
132
test()133 void test() {
134 void *p = 0;
135 f(0, p);
136 }
137 }
138
139 // rdar://problem/8537391
140 namespace test3 {
141 struct Foo {
142 template <void F(char)> static inline void foo();
143 };
144
145 class Bar {
146 template<typename T> static inline void wobble(T ch);
147
148 public:
madness()149 static void madness() {
150 Foo::foo<wobble<char> >();
151 }
152 };
153 }
154
155 namespace test4 {
156
157 template <class> struct a { using b = const float; };
158 template <class c> using d = typename a<c>::b;
159
e(d<c> *,c)160 template <class c> void e(d<c> *, c) {}
161 template void e(const float *, int);
162
163 } // namespace test4
164
165 // Verify that we can deduce enum-typed arguments correctly.
166 namespace test14 {
167 enum E { E0, E1 };
168 template <E> struct A {};
foo(const A<e> & a)169 template <E e> void foo(const A<e> &a) {}
170
test()171 void test() {
172 A<E0> a;
173 foo(a);
174 }
175 }
176
177 namespace PR21536 {
178 template<typename ...T> struct X;
179 template<typename A, typename ...B> struct S {
180 static_assert(sizeof...(B) == 1, "");
fPR21536::S181 void f() {
182 using T = A;
183 using T = int;
184
185 using U = X<B...>;
186 using U = X<int>;
187 }
188 };
189 template<typename ...T> void f(S<T...>);
g()190 void g() { f(S<int, int>()); }
191 }
192
193 namespace PR19372 {
194 template <template<typename...> class C, typename ...Us> struct BindBack {
195 template <typename ...Ts> using apply = C<Ts..., Us...>;
196 };
197 template <typename, typename...> struct Y;
198 template <typename ...Ts> using Z = Y<Ts...>;
199
200 using T = BindBack<Z, int>::apply<>;
201 using T = Z<int>;
202
203 using U = BindBack<Z, int, int>::apply<char>;
204 using U = Z<char, int, int>;
205
206 namespace BetterReduction {
207 template<typename ...> struct S;
208 template<typename ...A> using X = S<A...>; // expected-note {{parameter}}
209 template<typename ...A> using Y = X<A..., A...>;
210 template<typename ...A> using Z = X<A..., 1, 2, 3>; // expected-error {{must be a type}}
211
212 using T = Y<int>;
213 using T = S<int, int>;
214 }
215 }
216
217 namespace PR18645 {
218 template<typename F> F Quux(F &&f);
219 auto Baz = Quux(Quux<float>);
220 }
221
222 namespace NonDeducedNestedNameSpecifier {
223 template<typename T> struct A {
224 template<typename U> struct B {
BNonDeducedNestedNameSpecifier::A::B225 B(int) {}
226 };
227 };
228
229 template<typename T> int f(A<T>, typename A<T>::template B<T>);
230 int k = f(A<int>(), 0);
231 }
232
233 namespace PR27601_RecursivelyInheritedBaseSpecializationsDeductionAmbiguity {
234 namespace ns1 {
235
236 template<class...> struct B { };
237 template<class H, class ... Ts> struct B<H, Ts...> : B<> { };
238 template<class ... Ts> struct D : B<Ts...> { };
239
f(B<T,Ts...> &)240 template<class T, class ... Ts> void f(B<T, Ts...> &) { }
241
main()242 int main() {
243 D<int, char> d;
244 f<int>(d);
245 }
246 } //end ns1
247
248 namespace ns2 {
249
250 template <int i, typename... Es> struct tup_impl;
251
252 template <int i> struct tup_impl<i> {}; // empty tail
253
254 template <int i, typename Head, typename... Tail>
255 struct tup_impl<i, Head, Tail...> : tup_impl<i + 1, Tail...> {
256 using value_type = Head;
257 Head head;
258 };
259
260 template <typename... Es> struct tup : tup_impl<0, Es...> {};
261
262 template <typename Head, int i, typename... Tail>
get_helper(tup_impl<i,Head,Tail...> & t)263 Head &get_helper(tup_impl<i, Head, Tail...> &t) {
264 return t.head;
265 }
266
267 template <typename Head, int i, typename... Tail>
get_helper(tup_impl<i,Head,Tail...> const & t)268 Head const &get_helper(tup_impl<i, Head, Tail...> const &t) {
269 return t.head;
270 }
271
main()272 int main() {
273 tup<int, double, char> t;
274 get_helper<double>(t);
275 return 0;
276 }
277 } // end ns2
278 }
279
280 namespace multiple_deduction_different_type {
281 template<typename T, T v> struct X {};
282 template<template<typename T, T> class X, typename T, typename U, int N>
f(X<T,N>,X<U,N>)283 void f(X<T, N>, X<U, N>) {} // expected-note 2{{values of conflicting types}}
284 template<template<typename T, T> class X, typename T, typename U, const int *N>
g(X<T,N>,X<U,N>)285 void g(X<T, N>, X<U, N>) {} // expected-note 0-2{{values of conflicting types}}
286 int n;
h()287 void h() {
288 f(X<int, 1+1>(), X<unsigned int, 3-1>()); // expected-error {{no matching function}}
289 f(X<unsigned int, 1+1>(), X<int, 3-1>()); // expected-error {{no matching function}}
290 #if __cplusplus > 201402L
291 g(X<const int*, &n>(), X<int*, &n + 1 - 1>()); // expected-error {{no matching function}}
292 g(X<int*, &n>(), X<const int*, &n + 1 - 1>()); // expected-error {{no matching function}}
293 #endif
294 }
295
296 template<template<typename T, T> class X, typename T, typename U, T N>
x(X<T,N>,int (*)[N],X<U,N>)297 void x(X<T, N>, int(*)[N], X<U, N>) {} // expected-note 1+{{candidate}}
298 template<template<typename T, T> class X, typename T, typename U, T N>
x(int (*)[N],X<T,N>,X<U,N>)299 void x(int(*)[N], X<T, N>, X<U, N>) {} // expected-note 1+{{candidate}}
300 int arr[3];
y()301 void y() {
302 x(X<int, 3>(), &arr, X<int, 3>());
303 x(&arr, X<int, 3>(), X<int, 3>());
304
305 x(X<int, 3>(), &arr, X<char, 3>()); // expected-error {{no matching function}}
306 x(&arr, X<int, 3>(), X<char, 3>()); // expected-error {{no matching function}}
307
308 x(X<char, 3>(), &arr, X<char, 3>());
309 x(&arr, X<char, 3>(), X<char, 3>());
310 }
311 }
312
313 namespace nullptr_deduction {
314 using nullptr_t = decltype(nullptr);
315
316 template<typename T, T v> struct X {};
f(X<T,v>)317 template<typename T, T v> void f(X<T, v>) {
318 static_assert(!v, ""); // expected-warning 2{{implicit conversion of nullptr constant to 'bool'}}
319 }
g()320 void g() {
321 f(X<int*, nullptr>()); // expected-note {{instantiation of}}
322 f(X<nullptr_t, nullptr>()); // expected-note {{instantiation of}}
323 }
324
325 template<template<typename T, T> class X, typename T, int *P>
f0(X<T,P>)326 void f0(X<T, P>) {} // expected-note {{deduced non-type template argument does not have the same type as the corresponding template parameter ('std::nullptr_t' vs 'int *')}}
h0()327 void h0() {
328 f0(X<int*, nullptr>());
329 f0(X<nullptr_t, nullptr>()); // expected-error {{no matching function}}
330 }
331
332 template<template<typename T, T> class X, typename T, typename U, int *P>
f1(X<T,P>,X<U,P>)333 void f1(X<T, P>, X<U, P>) {} // expected-note 2{{values of conflicting types}}
h()334 void h() {
335 f1(X<int*, nullptr>(), X<nullptr_t, nullptr>()); // expected-error {{no matching function}}
336 f1(X<nullptr_t, nullptr>(), X<int*, nullptr>()); // expected-error {{no matching function}}
337 }
338
339 template<template<typename T, T> class X, typename T, typename U, nullptr_t P>
f2(X<T,P>,X<U,P>)340 void f2(X<T, P>, X<U, P>) {} // expected-note 2{{values of conflicting types}}
i()341 void i() {
342 f2(X<int*, nullptr>(), X<nullptr_t, nullptr>()); // expected-error {{no matching function}}
343 f2(X<nullptr_t, nullptr>(), X<int*, nullptr>()); // expected-error {{no matching function}}
344 }
345 }
346
347 namespace member_pointer {
348 struct A { void f(int); };
349 template<typename T, void (A::*F)(T)> struct B;
350 template<typename T> struct C;
351 template<typename T, void (A::*F)(T)> struct C<B<T, F>> {
Cmember_pointer::C352 C() { A a; T t; (a.*F)(t); }
353 };
354 C<B<int, &A::f>> c;
355 }
356
357 namespace deduction_substitution_failure {
358 template<typename T> struct Fail { typedef typename T::error error; }; // expected-error 2{{prior to '::'}}
359
360 template<typename T, typename U> struct A {};
361 template<typename T> struct A<T, typename Fail<T>::error> {}; // expected-note {{instantiation of}}
362 A<int, int> ai; // expected-note {{during template argument deduction for class template partial specialization 'A<T, typename Fail<T>::error>' [with T = int]}} expected-note {{in instantiation of template class 'deduction_substitution_failure::A<int, int>'}}
363
364 template<typename T, typename U> int B; // expected-warning 0-1 {{extension}}
365 template<typename T> int B<T, typename Fail<T>::error> {}; // expected-note {{instantiation of}}
366 int bi = B<char, char>; // expected-note {{during template argument deduction for variable template partial specialization 'B<T, typename Fail<T>::error>' [with T = char]}}
367 }
368
369 namespace deduction_after_explicit_pack {
f(T...t,int & r,U * u)370 template<typename ...T, typename U> int *f(T ...t, int &r, U *u) {
371 return u;
372 }
g(T...t,int & r,U * u)373 template<typename U, typename ...T> int *g(T ...t, int &r, U *u) {
374 return u;
375 }
h(float a,double b,int c)376 void h(float a, double b, int c) {
377 f<float&, double&>(a, b, c, &c); // ok
378 g<int, float&, double&>(a, b, c, &c); // ok
379 }
380
381 template<class... ExtraArgs>
382 int test(ExtraArgs..., unsigned vla_size, const char *input);
383 int n = test(0, "");
384
385 template <typename... T> void i(T..., int, T..., ...); // expected-note 5{{deduced packs of different lengths}}
j()386 void j() {
387 i(0);
388 i(0, 1); // expected-error {{no match}}
389 i(0, 1, 2); // expected-error {{no match}}
390 i<>(0);
391 i<>(0, 1); // expected-error {{no match}}
392 i<>(0, 1, 2); // expected-error {{no match}}
393 i<int, int>(0, 1, 2, 3, 4);
394 i<int, int>(0, 1, 2, 3, 4, 5); // expected-error {{no match}}
395 }
396
397 // GCC alarmingly accepts this by deducing T={int} by matching the second
398 // parameter against the first argument, then passing the first argument
399 // through the first parameter.
400 template<typename... T> struct X { X(int); operator int(); };
401 template<typename... T> void p(T..., X<T...>, ...); // expected-note {{deduced packs of different lengths for parameter 'T' (<> vs. <int>)}}
q()402 void q() { p(X<int>(0), 0); } // expected-error {{no match}}
403
404 struct A {
405 template <typename T> void f(T, void *, int = 0); // expected-note 2{{no known conversion from 'double' to 'void *' for 2nd argument}}
406 void f(); // expected-note 2{{requires 0}}
407
408 template <typename T> static void g(T, void *, int = 0); // expected-note 2{{no known conversion from 'double' to 'void *' for 2nd argument}}
409 void g(); // expected-note 2{{requires 0}}
410
hdeduction_after_explicit_pack::A411 void h() {
412 f(1.0, 2.0); // expected-error {{no match}}
413 g(1.0, 2.0); // expected-error {{no match}}
414 }
415 };
f(A a)416 void f(A a) {
417 a.f(1.0, 2.0); // expected-error {{no match}}
418 a.g(1.0, 2.0); // expected-error {{no match}}
419 }
420 }
421
422 namespace overload_vs_pack {
423 void f(int);
424 void f(float);
425 void g(double);
426
427 template<typename ...T> struct X {};
428 template<typename ...T> void x(T...);
429
430 template<typename ...T> struct Y { typedef int type(typename T::error...); };
431 template<> struct Y<int, float, double> { typedef int type; };
432
433 template<typename ...T> typename Y<T...>::type g1(X<T...>, void (*...fns)(T)); // expected-note {{deduced conflicting types for parameter 'T' (<int, float> vs. <(no value), double>)}}
434 template<typename ...T> typename Y<T...>::type g2(void(*)(T...), void (*...fns)(T)); // expected-note {{deduced conflicting types for parameter 'T' (<int, float> vs. <(no value), double>)}}
435
436 template<typename T> int &h1(decltype(g1(X<int, float, T>(), f, f, g)) *p);
437 template<typename T> float &h1(...);
438
439 template<typename T> int &h2(decltype(g2(x<int, float, T>, f, f, g)) *p);
440 template<typename T> float &h2(...);
441
442 int n1 = g1(X<int, float>(), f, g); // expected-error {{no matching function}}
443 int n2 = g2(x<int, float>, f, g); // expected-error {{no matching function}}
444
445 int &a1 = h1<double>(0); // ok, skip deduction for 'f's, deduce matching value from 'g'
446 int &a2 = h2<double>(0);
447
448 float &b1 = h1<float>(0); // deduce mismatching value from 'g', so we do not trigger instantiation of Y
449 float &b2 = h2<float>(0);
450
451 template<typename ...T> int partial_deduction(void (*...f)(T)); // expected-note {{deduced incomplete pack <(no value), double> for template parameter 'T'}}
452 int pd1 = partial_deduction(f, g); // expected-error {{no matching function}}
453
454 template<typename ...T> int partial_deduction_2(void (*...f)(T), ...); // expected-note {{deduced incomplete pack <(no value), double> for template parameter 'T'}}
455 int pd2 = partial_deduction_2(f, g); // expected-error {{no matching function}}
456
457 namespace cwg_example {
458 void f(char, char);
459 void f(int, int);
460 void x(int, char);
461
462 template<typename T, typename ...U> void j(void(*)(U...), void (*...fns)(T, U));
test()463 void test() { j(x, f, x); }
464 }
465 }
466
467 namespace b29946541 {
468 template<typename> class A {};
469 template<typename T, typename U, template<typename, typename> class C>
470 void f(C<T, U>); // expected-note {{failed template argument deduction}}
g(A<int> a)471 void g(A<int> a) { f(a); } // expected-error {{no match}}
472 }
473
474 namespace deduction_from_empty_list {
475 template<int M, int N = 5> void f(int (&&)[N], int (&&)[N]) { // expected-note {{1 vs. 2}}
476 static_assert(M == N, "");
477 }
478
test()479 void test() {
480 f<5>({}, {});
481 f<1>({}, {0});
482 f<1>({0}, {});
483 f<1>({0}, {0});
484 f<1>({0}, {0, 1}); // expected-error {{no matching}}
485 }
486 }
487
488 namespace check_extended_pack {
489 template<typename T> struct X { typedef int type; };
490 template<typename ...T> void f(typename X<T>::type...);
491 template<typename T> void f(T, int, int);
g()492 void g() {
493 f<int>(0, 0, 0);
494 }
495
496 template<int, int*> struct Y {};
497 template<int ...N> void g(Y<N...>); // expected-note {{deduced non-type template argument does not have the same type as the corresponding template parameter ('int *' vs 'int')}}
498 int n;
h()499 void h() { g<0>(Y<0, &n>()); } // expected-error {{no matching function}}
500 }
501
502 namespace dependent_template_template_param_non_type_param_type {
503 template<int N> struct A {
504 template<typename V = int, V M = 12, V (*Y)[M], template<V (*v)[M]> class W>
505 A(W<Y>);
506 };
507
508 int n[12];
509 template<int (*)[12]> struct Q {};
510 Q<&n> qn;
511 A<0> a(qn);
512 }
513
514 namespace dependent_list_deduction {
a(const int (&)[V])515 template<typename T, T V> void a(const int (&)[V]) {
516 static_assert(is_same<T, decltype(sizeof(0))>::value, "");
517 static_assert(V == 3, "");
518 }
b(const T (&)[V])519 template<typename T, T V> void b(const T (&)[V]) {
520 static_assert(is_same<T, int>::value, "");
521 static_assert(V == 3, "");
522 }
c(const T (&)[V])523 template<typename T, T V> void c(const T (&)[V]) {
524 static_assert(is_same<T, decltype(sizeof(0))>::value, "");
525 static_assert(V == 3, "");
526 }
d()527 void d() {
528 a({1, 2, 3});
529 #if __cplusplus <= 201402L
530 // expected-error@-2 {{no match}} expected-note@-15 {{couldn't infer template argument 'T'}}
531 #endif
532 b({1, 2, 3});
533 c({{}, {}, {}});
534 #if __cplusplus <= 201402L
535 // expected-error@-2 {{no match}} expected-note@-12 {{couldn't infer template argument 'T'}}
536 #endif
537 }
538
539 template<typename ...T> struct X;
540 template<int ...T> struct Y;
f(const T (&...p)[V])541 template<typename ...T, T ...V> void f(const T (&...p)[V]) {
542 static_assert(is_same<X<T...>, X<int, char, char>>::value, "");
543 static_assert(is_same<Y<V...>, Y<3, 2, 4>>::value, "");
544 }
g(const T (&...p)[V])545 template<typename ...T, T ...V> void g(const T (&...p)[V]) {
546 static_assert(is_same<X<T...>, X<int, decltype(sizeof(0))>>::value, "");
547 static_assert(is_same<Y<V...>, Y<2, 3>>::value, "");
548 }
h()549 void h() {
550 f({1, 2, 3}, {'a', 'b'}, "foo");
551 g({1, 2}, {{}, {}, {}});
552 #if __cplusplus <= 201402
553 // expected-error@-2 {{no match}}
554 // expected-note@-9 {{deduced incomplete pack}}
555 // We deduce V$1 = (size_t)3, which in C++1z also deduces T$1 = size_t.
556 #endif
557 }
558 }
559
560 namespace designators {
561 template<typename T, int N> constexpr int f(T (&&)[N]) { return N; } // expected-note 2{{couldn't infer template argument 'T'}}
562 static_assert(f({1, 2, [20] = 3}) == 3, ""); // expected-error {{no matching function}} expected-warning 2{{C99}} expected-note {{}}
563
564 static_assert(f({.a = 1, .b = 2}) == 3, ""); // expected-error {{no matching function}}
565 }
566
567 namespace nested_packs {
568 template<typename ...T, typename ...U> void f(T (*...f)(U...)); // expected-note {{deduced packs of different lengths for parameter 'U' (<> vs. <int>)}}
g()569 void g() { f(g); f(g, g); f(g, g, g); }
h(int)570 void h(int) { f(h); f(h, h); f(h, h, h); }
i()571 void i() { f(g, h); } // expected-error {{no matching function}}
572
573 #if __cplusplus >= 201703L
574 template<auto ...A> struct Q {};
575 template<typename ...T, T ...A, T ...B> void q(Q<A...>, Q<B...>); // #q
qt(Q<> q0,Q<1,2> qii,Q<1,2,3> qiii)576 void qt(Q<> q0, Q<1, 2> qii, Q<1, 2, 3> qiii) {
577 q(q0, q0);
578 q(qii, qii);
579 q(qii, qiii); // expected-error {{no match}} expected-note@#q {{deduced packs of different lengths for parameter 'T' (<int, int> vs. <int, int, int>)}}
580 q(q0, qiii); // expected-error {{no match}} expected-note@#q {{deduced packs of different lengths for parameter 'T' (<> vs. <int, int, int>)}}
581 }
582 #endif
583 }
584
585 namespace PR44890 {
586 template<typename ...Ts>
587 struct tuple {};
588
589 template<int I, typename ...Ts>
get0(const tuple<Ts...> & t)590 int get0(const tuple<Ts...> &t) { return 0; }
591
592 template<typename ...Ts> struct tuple_wrapper : tuple<Ts...> {
getPR44890::tuple_wrapper593 template<int I> int get() { return get0<0, Ts...>(*this); }
594 };
595
f()596 int f() {
597 tuple_wrapper<int> w;
598 return w.get<0>();
599 }
600 }
601
602 namespace merge_size_only_deductions {
603 #if __cplusplus >= 201703L
604 // Based on a testcase by Hubert Tong.
605 template<typename ...> struct X {};
606 template<auto ...> struct Y {};
607 template<typename T> struct id { using Type = T; };
608
609 template<typename ...T, typename T::Type ...V>
610 int f(X<char [V] ...>, Y<V ...>, X<T ...>);
611
612 using size_t = __SIZE_TYPE__;
613 int a = f(X<char [1], char [2]>(), Y<(size_t)1, (size_t)2>(), X<id<size_t>, id<size_t>>());
614 int b = f(X<char [1], char [2]>(), Y<1, 2>(), X<id<int>, id<int>>());
615 #endif
616 }
617
618 namespace PR49724 {
619 struct A;
620 template<int A::*> class X {};
621 template<int A::*P> void f(X<P>);
g(X<nullptr> x)622 void g(X<nullptr> x) { f(x); }
623
624 template<void (A::*)()> class Y {};
625 template<void (A::*P)()> void f(Y<P>);
g(Y<nullptr> y)626 void g(Y<nullptr> y) { f(y); }
627 }
628