1 // RUN: %clang_cc1 -fsyntax-only -verify %s 2 template<typename T, int N = 2> struct X; // expected-note{{template is declared here}} 3 4 X<int, 1> *x1; 5 X<int> *x2; 6 7 X<> *x3; // expected-error{{too few template arguments for class template 'X'}} 8 9 template<typename U = float, int M> struct X; 10 11 X<> *x4; 12 13 template<typename T = int> struct Z { }; 14 template struct Z<>; 15 16 // PR4362 17 template<class T> struct a { }; 18 template<> struct a<int> { static const bool v = true; }; 19 20 template<class T, bool = a<T>::v> struct p { }; // expected-error {{no member named 'v'}} 21 22 template struct p<bool>; // expected-note {{in instantiation of default argument for 'p<bool>' required here}} 23 template struct p<int>; 24 25 // PR5187 26 template<typename T, typename U> 27 struct A; 28 29 template<typename T, typename U = T> 30 struct A; 31 32 template<typename T, typename U> 33 struct A { 34 void f(A<T>); 35 }; 36 37 template<typename T> 38 struct B { }; 39 40 template<> 41 struct B<void> { 42 typedef B<void*> type; 43 }; 44 45 // Nested default arguments for template parameters. 46 template<typename T> struct X1 { }; 47 48 template<typename T> 49 struct X2 { 50 template<typename U = typename X1<T>::type> // expected-error{{no type named 'type' in 'X1<int>'}} \ 51 // expected-error{{no type named 'type' in 'X1<char>'}} 52 struct Inner1 { }; // expected-note{{template is declared here}} 53 54 template<T Value = X1<T>::value> // expected-error{{no member named 'value' in 'X1<int>'}} \ 55 // expected-error{{no member named 'value' in 'X1<char>'}} 56 struct NonType1 { }; // expected-note{{template is declared here}} 57 58 template<T Value> 59 struct Inner2 { }; 60 61 template<typename U> 62 struct Inner3 { 63 template<typename X = T, typename V = U> 64 struct VeryInner { }; 65 66 template<T Value1 = sizeof(T), T Value2 = sizeof(U), 67 T Value3 = Value1 + Value2> 68 struct NonType2 { }; 69 }; 70 }; 71 72 X2<int> x2i; // expected-note{{in instantiation of template class 'X2<int>' requested here}} 73 X2<int>::Inner1<float> x2iif; 74 75 X2<int>::Inner1<> x2bad; // expected-error{{too few template arguments for class template 'Inner1'}} 76 77 X2<int>::NonType1<'a'> x2_nontype1; 78 X2<int>::NonType1<> x2_nontype1_bad; // expected-error{{too few template arguments for class template 'NonType1'}} 79 80 // Check multi-level substitution into template type arguments 81 X2<int>::Inner3<float>::VeryInner<> vi; 82 X2<char>::Inner3<int>::NonType2<> x2_deep_nontype; // expected-note{{in instantiation of template class 'X2<char>' requested here}} 83 84 template<typename T, typename U> 85 struct is_same { static const bool value = false; }; 86 87 template<typename T> 88 struct is_same<T, T> { static const bool value = true; }; 89 90 int array1[is_same<__typeof__(vi), 91 X2<int>::Inner3<float>::VeryInner<int, float> >::value? 1 : -1]; 92 93 int array2[is_same<__typeof(x2_deep_nontype), 94 X2<char>::Inner3<int>::NonType2<sizeof(char), sizeof(int), 95 sizeof(char)+sizeof(int)> >::value? 1 : -1]; 96 97 // Template template parameter defaults 98 template<template<typename T> class X = X2> struct X3 { }; 99 int array3[is_same<X3<>, X3<X2> >::value? 1 : -1]; 100 101 struct add_pointer { 102 template<typename T> 103 struct apply { 104 typedef T* type; 105 }; 106 }; 107 108 template<typename T, template<typename> class X = T::template apply> 109 struct X4; 110 int array4[is_same<X4<add_pointer>, 111 X4<add_pointer, add_pointer::apply> >::value? 1 : -1]; 112 113 template<int> struct X5 {}; // expected-note{{has a different type 'int'}} 114 template<long> struct X5b {}; 115 template<typename T, 116 template<T> class B = X5> // expected-error{{template template argument has different}} \ 117 // expected-note{{previous non-type template parameter}} 118 struct X6 {}; 119 120 X6<int> x6a; 121 X6<long> x6b; // expected-note{{while checking a default template argument}} 122 X6<long, X5b> x6c; 123 124 125 template<template<class> class X = B<int> > struct X7; // expected-error{{must be a class template}} 126 127 namespace PR9643 { 128 template<typename T> class allocator {}; 129 template<typename T, typename U = allocator<T> > class vector {}; 130 131 template<template<typename U, typename = allocator<U> > class container, 132 typename DT> 133 container<DT> initializer(const DT& d) { 134 return container<DT>(); 135 } 136 137 void f() { 138 vector<int, allocator<int> > v = initializer<vector>(5); 139 } 140 } 141 142 namespace PR16288 { 143 template<typename X> 144 struct S { 145 template<typename T = int, typename U> // expected-warning {{C++11}} 146 void f(); 147 }; 148 template<typename X> 149 template<typename T, typename U> 150 void S<X>::f() {} 151 } 152 153 namespace DR1635 { 154 template <class T> struct X { 155 template <class U = typename T::type> static void f(int) {} // expected-error {{type 'int' cannot be used prior to '::' because it has no members}} \ 156 // expected-warning {{C++11}} 157 static void f(...) {} 158 }; 159 160 int g() { X<int>::f(0); } // expected-note {{in instantiation of template class 'DR1635::X<int>' requested here}} 161 } 162