deduction.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
  2. // Template argument deduction with template template parameters.
  3. template<typename T, template<T> class A>
  4. struct X0 {
  5. static const unsigned value = 0;
  6. };
  7. template<template<int> class A>
  8. struct X0<int, A> {
  9. static const unsigned value = 1;
  10. };
  11. template<int> struct X0i;
  12. template<long> struct X0l;
  13. int array_x0a[X0<long, X0l>::value == 0? 1 : -1];
  14. int array_x0b[X0<int, X0i>::value == 1? 1 : -1];
  15. template<typename T, typename U>
  16. struct is_same {
  17. static const bool value = false;
  18. };
  19. template<typename T>
  20. struct is_same<T, T> {
  21. static const bool value = true;
  22. };
  23. template<typename T> struct allocator { };
  24. template<typename T, typename Alloc = allocator<T> > struct vector {};
  25. // Fun with meta-lambdas!
  26. struct _1 {};
  27. struct _2 {};
  28. // Replaces all occurrences of _1 with Arg1 and _2 with Arg2 in T.
  29. template<typename T, typename Arg1, typename Arg2>
  30. struct Replace {
  31. typedef T type;
  32. };
  33. // Replacement of the whole type.
  34. template<typename Arg1, typename Arg2>
  35. struct Replace<_1, Arg1, Arg2> {
  36. typedef Arg1 type;
  37. };
  38. template<typename Arg1, typename Arg2>
  39. struct Replace<_2, Arg1, Arg2> {
  40. typedef Arg2 type;
  41. };
  42. // Replacement through cv-qualifiers
  43. template<typename T, typename Arg1, typename Arg2>
  44. struct Replace<const T, Arg1, Arg2> {
  45. typedef typename Replace<T, Arg1, Arg2>::type const type;
  46. };
  47. // Replacement of templates
  48. template<template<typename> class TT, typename T1, typename Arg1, typename Arg2>
  49. struct Replace<TT<T1>, Arg1, Arg2> {
  50. typedef TT<typename Replace<T1, Arg1, Arg2>::type> type;
  51. };
  52. template<template<typename, typename> class TT, typename T1, typename T2,
  53. typename Arg1, typename Arg2>
  54. struct Replace<TT<T1, T2>, Arg1, Arg2> {
  55. typedef TT<typename Replace<T1, Arg1, Arg2>::type,
  56. typename Replace<T2, Arg1, Arg2>::type> type;
  57. };
  58. // Just for kicks...
  59. template<template<typename, typename> class TT, typename T1,
  60. typename Arg1, typename Arg2>
  61. struct Replace<TT<T1, _2>, Arg1, Arg2> {
  62. typedef TT<typename Replace<T1, Arg1, Arg2>::type, Arg2> type;
  63. };
  64. int array0[is_same<Replace<_1, int, float>::type, int>::value? 1 : -1];
  65. int array1[is_same<Replace<const _1, int, float>::type, const int>::value? 1 : -1];
  66. int array2[is_same<Replace<vector<_1>, int, float>::type, vector<int> >::value? 1 : -1];
  67. int array3[is_same<Replace<vector<const _1>, int, float>::type, vector<const int> >::value? 1 : -1];
  68. int array4[is_same<Replace<vector<int, _2>, double, float>::type, vector<int, float> >::value? 1 : -1];
  69. // PR5911
  70. template <typename T, int N> void f(const T (&a)[N]);
  71. int iarr[] = { 1 };
  72. void test_PR5911() { f(iarr); }
  73. // Must not examine base classes of incomplete type during template argument
  74. // deduction.
  75. namespace PR6257 {
  76. template <typename T> struct X {
  77. template <typename U> X(const X<U>& u);
  78. };
  79. struct A;
  80. void f(A& a);
  81. void f(const X<A>& a);
  82. void test(A& a) { (void)f(a); }
  83. }
  84. // PR7463
  85. namespace PR7463 {
  86. const int f ();
  87. template <typename T_> void g (T_&); // expected-note{{T_ = int}}
  88. void h (void) { g(f()); } // expected-error{{no matching function for call}}
  89. }
  90. namespace test0 {
  91. template <class T> void make(const T *(*fn)()); // expected-note {{candidate template ignored: can't deduce a type for 'T' that would make 'const T' equal 'char'}}
  92. char *char_maker();
  93. void test() {
  94. make(char_maker); // expected-error {{no matching function for call to 'make'}}
  95. }
  96. }
  97. namespace test1 {
  98. template<typename T> void foo(const T a[3][3]);
  99. void test() {
  100. int a[3][3];
  101. foo(a);
  102. }
  103. }
  104. // PR7708
  105. namespace test2 {
  106. template<typename T> struct Const { typedef void const type; };
  107. template<typename T> void f(T, typename Const<T>::type*);
  108. template<typename T> void f(T, void const *);
  109. void test() {
  110. void *p = 0;
  111. f(0, p);
  112. }
  113. }
  114. // rdar://problem/8537391
  115. namespace test3 {
  116. struct Foo {
  117. template <void F(char)> static inline void foo();
  118. };
  119. class Bar {
  120. template<typename T> static inline void wobble(T ch);
  121. public:
  122. static void madness() {
  123. Foo::foo<wobble<char> >();
  124. }
  125. };
  126. }
  127. // Verify that we can deduce enum-typed arguments correctly.
  128. namespace test14 {
  129. enum E { E0, E1 };
  130. template <E> struct A {};
  131. template <E e> void foo(const A<e> &a) {}
  132. void test() {
  133. A<E0> a;
  134. foo(a);
  135. }
  136. }
  137. namespace PR21536 {
  138. template<typename ...T> struct X;
  139. template<typename A, typename ...B> struct S {
  140. static_assert(sizeof...(B) == 1, "");
  141. void f() {
  142. using T = A;
  143. using T = int;
  144. using U = X<B...>;
  145. using U = X<int>;
  146. }
  147. };
  148. template<typename ...T> void f(S<T...>);
  149. void g() { f(S<int, int>()); }
  150. }
  151. namespace PR19372 {
  152. template <template<typename...> class C, typename ...Us> struct BindBack {
  153. template <typename ...Ts> using apply = C<Ts..., Us...>;
  154. };
  155. template <typename, typename...> struct Y;
  156. template <typename ...Ts> using Z = Y<Ts...>;
  157. using T = BindBack<Z, int>::apply<>;
  158. using T = Z<int>;
  159. using U = BindBack<Z, int, int>::apply<char>;
  160. using U = Z<char, int, int>;
  161. namespace BetterReduction {
  162. template<typename ...> struct S;
  163. template<typename ...A> using X = S<A...>; // expected-note {{parameter}}
  164. template<typename ...A> using Y = X<A..., A...>;
  165. template<typename ...A> using Z = X<A..., 1, 2, 3>; // expected-error {{must be a type}}
  166. using T = Y<int>;
  167. using T = S<int, int>;
  168. }
  169. }
  170. namespace PR18645 {
  171. template<typename F> F Quux(F &&f);
  172. auto Baz = Quux(Quux<float>);
  173. }