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}} 51 struct Inner1 { }; 52 53 template<T Value = X1<T>::value> // expected-error{{no member named 'value'}} 54 struct NonType1 { }; 55 56 template<T Value> 57 struct Inner2 { }; 58 59 template<typename U> 60 struct Inner3 { 61 template<typename X = T, typename V = U> 62 struct VeryInner { }; 63 64 template<T Value1 = sizeof(T), T Value2 = sizeof(U), 65 T Value3 = Value1 + Value2> 66 struct NonType2 { }; 67 }; 68 }; 69 70 X2<int> x2i; 71 X2<int>::Inner1<float> x2iif; 72 73 X2<int>::Inner1<> x2bad; // expected-note{{instantiation of default argument}} 74 75 X2<int>::NonType1<'a'> x2_nontype1; 76 X2<int>::NonType1<> x2_nontype1_bad; // expected-note{{instantiation of default argument}} 77 78 // Check multi-level substitution into template type arguments 79 X2<int>::Inner3<float>::VeryInner<> vi; 80 X2<char>::Inner3<int>::NonType2<> x2_deep_nontype; 81 82 template<typename T, typename U> 83 struct is_same { static const bool value = false; }; 84 85 template<typename T> 86 struct is_same<T, T> { static const bool value = true; }; 87 88 int array1[is_same<__typeof__(vi), 89 X2<int>::Inner3<float>::VeryInner<int, float> >::value? 1 : -1]; 90 91 int array2[is_same<__typeof(x2_deep_nontype), 92 X2<char>::Inner3<int>::NonType2<sizeof(char), sizeof(int), 93 sizeof(char)+sizeof(int)> >::value? 1 : -1]; 94 95 // Template template parameter defaults 96 template<template<typename T> class X = X2> struct X3 { }; 97 int array3[is_same<X3<>, X3<X2> >::value? 1 : -1]; 98 99 struct add_pointer { 100 template<typename T> 101 struct apply { 102 typedef T* type; 103 }; 104 }; 105 106 template<typename T, template<typename> class X = T::template apply> 107 struct X4; 108 int array4[is_same<X4<add_pointer>, 109 X4<add_pointer, add_pointer::apply> >::value? 1 : -1]; 110 111 template<int> struct X5 {}; // expected-note{{has a different type 'int'}} 112 template<long> struct X5b {}; 113 template<typename T, 114 template<T> class B = X5> // expected-error{{template template argument has different}} \ 115 // expected-note{{previous non-type template parameter}} 116 struct X6 {}; 117 118 X6<int> x6a; 119 X6<long> x6b; // expected-note{{while checking a default template argument}} 120 X6<long, X5b> x6c; 121 122 123 template<template<class> class X = B<int> > struct X7; // expected-error{{must be a class template}} 124 125 namespace PR9643 { 126 template<typename T> class allocator {}; 127 template<typename T, typename U = allocator<T> > class vector {}; 128 129 template<template<typename U, typename = allocator<U> > class container, 130 typename DT> 131 container<DT> initializer(const DT& d) { 132 return container<DT>(); 133 } 134 135 void f() { 136 vector<int, allocator<int> > v = initializer<vector>(5); 137 } 138 } 139 140 namespace PR16288 { 141 template<typename X> 142 struct S { 143 template<typename T = int, typename U> // expected-warning {{C++11}} 144 void f(); 145 }; 146 template<typename X> 147 template<typename T, typename U> 148 void S<X>::f() {} 149 } 150