Clang Project

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