1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
3 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
4 template<typename T
, int N
= 2> struct X
; // expected-note{{template is declared here}}
9 X
<> *x3
; // expected-error{{too few template arguments for class template 'X'}}
11 template<typename U
= float, int M
> struct X
;
15 template<typename T
= int> struct Z
{ };
19 template<class T
> struct a
{ };
20 template<> struct a
<int> { static const bool v
= true; };
22 template<class T
, bool = a
<T
>::v
> struct p
{ }; // expected-error {{no member named 'v'}}
24 template struct p
<bool>; // expected-note {{in instantiation of default argument for 'p<bool>' required here}}
25 template struct p
<int>;
28 template<typename T
, typename U
>
31 template<typename T
, typename U
= T
>
34 template<typename T
, typename U
>
44 typedef B
<void*> type
;
47 // Nested default arguments for template parameters.
48 template<typename T
> struct X1
{ };
52 template<typename U
= typename X1
<T
>::type
> // expected-error{{no type named 'type' in 'X1<int>'}} \
53 // expected-error{{no type named 'type' in 'X1<char>'}}
54 struct Inner1
{ }; // expected-note{{template is declared here}}
56 template<T Value
= X1
<T
>::value
> // expected-error{{no member named 'value' in 'X1<int>'}} \
57 // expected-error{{no member named 'value' in 'X1<char>'}}
58 struct NonType1
{ }; // expected-note{{template is declared here}}
65 template<typename X
= T
, typename V
= U
>
68 template<T Value1
= sizeof(T
), T Value2
= sizeof(U
),
69 T Value3
= Value1
+ Value2
>
74 X2
<int> x2i
; // expected-note{{in instantiation of template class 'X2<int>' requested here}}
75 X2
<int>::Inner1
<float> x2iif
;
77 X2
<int>::Inner1
<> x2bad
; // expected-error{{too few template arguments for class template 'Inner1'}}
79 X2
<int>::NonType1
<'a'> x2_nontype1
;
80 X2
<int>::NonType1
<> x2_nontype1_bad
; // expected-error{{too few template arguments for class template 'NonType1'}}
82 // Check multi-level substitution into template type arguments
83 X2
<int>::Inner3
<float>::VeryInner
<> vi
;
84 X2
<char>::Inner3
<int>::NonType2
<> x2_deep_nontype
; // expected-note{{in instantiation of template class 'X2<char>' requested here}}
86 template<typename T
, typename U
>
87 struct is_same
{ static const bool value
= false; };
90 struct is_same
<T
, T
> { static const bool value
= true; };
92 int array1
[is_same
<__typeof__(vi
),
93 X2
<int>::Inner3
<float>::VeryInner
<int, float> >::value
? 1 : -1];
95 int array2
[is_same
<__typeof(x2_deep_nontype
),
96 X2
<char>::Inner3
<int>::NonType2
<sizeof(char), sizeof(int),
97 sizeof(char)+sizeof(int)> >::value
? 1 : -1];
99 // Template template parameter defaults
100 template<template<typename T
> class X
= X2
> struct X3
{ };
101 int array3
[is_same
<X3
<>, X3
<X2
> >::value
? 1 : -1];
110 template<typename T
, template<typename
> class X
= T::template apply
>
112 int array4
[is_same
<X4
<add_pointer
>,
113 X4
<add_pointer
, add_pointer::apply
> >::value
? 1 : -1];
115 template<int> struct X5
{}; // expected-note{{has a different type 'int'}}
116 template<long> struct X5b
{};
118 template<T
> class B
= X5
> // expected-error{{template template argument has different}} \
119 // expected-note{{previous non-type template parameter}}
123 X6
<long> x6b
; // expected-note{{while checking a default template argument}}
127 template<template<class> class X
= B
<int> > struct X7
; // expected-error{{must be a class template}}
130 template<typename T
> class allocator
{};
131 template<typename T
, typename U
= allocator
<T
> > class vector
{};
133 template<template<typename U
, typename
= allocator
<U
> > class container
,
135 container
<DT
> initializer(const DT
& d
) {
136 return container
<DT
>();
140 vector
<int, allocator
<int> > v
= initializer
<vector
>(5);
147 template<typename T
= int, typename U
>
148 #if __cplusplus <= 199711L // C++03 or earlier modes
149 // expected-warning@-2 {{default template arguments for a function template are a C++11 extension}}
154 template<typename T
, typename U
>
159 template <class T
> struct X
{
160 template <class U
= typename
T::type
> static void f(int) {} // expected-error {{type 'int' cannot be used prior to '::' because it has no members}}
161 #if __cplusplus <= 199711L // C++03 or earlier modes
162 // expected-warning@-2 {{default template arguments for a function template are a C++11 extension}}
164 static void f(...) {}
167 int g() { X
<int>::f(0); } // expected-note {{in instantiation of template class 'DR1635::X<int>' requested here}}
170 namespace NondefDecls
{
171 template<typename T
> void f1() {
172 int g1(int defarg
= T::error
); // expected-error{{type 'int' cannot be used prior to '::' because it has no members}} \
173 // expected-note {{in instantiation of default function argument expression for 'g1<int>' required here}}
175 template void f1
<int>(); // expected-note{{in instantiation of function template specialization 'NondefDecls::f1<int>' requested here}}
178 template <typename T
>
180 C(T t
= ); // expected-error {{expected expression}}
185 // Make sure when substituting default template arguments we do it in the current context.
186 template<class T
, bool Val
= T::value
>
189 template<bool B
> struct Y
{
190 void f() { X
<Y
> xy
; }
191 static const bool value
= B
;
197 template<bool B
= T0::value
> struct XInner
{ static const bool value
= B
; };
199 template<bool B
> struct S
{ static const bool value
= B
; };
200 #if __cplusplus > 199711L
201 template<bool B
> struct Y
{
202 static constexpr bool f() { return typename X
<S
<B
>>::template XInner
<>{}.value
; }
203 static_assert(f() == B
, "");
214 template<typename
> struct A
{
215 template<typename
> friend void f();
216 template<typename
> friend struct X
;
218 template<typename
= int> void f(); // expected-warning 0-1{{extension}}
219 template<typename
= int> struct X
;
228 namespace unevaluated
{
230 template<int = 0> int f(int = a
); // expected-warning 0-1{{extension}}