1 // RUN: %clang_cc1 %s -fsyntax-only -std=c++23 -verify=expected,new
2 // RUN: %clang_cc1 %s -fsyntax-only -std=c++23 -fno-relaxed-template-template-args -verify=expected,old
5 template<class T
, class U
= T
> class B
{};
6 template<template<class> class P
, class T
> void f(P
<T
>);
7 // new-note@-1 {{deduced type 'B<[...], (default) int>' of 1st parameter does not match adjusted type 'B<[...], float>' of argument [with P = B, T = int]}}
8 // old-note@-2 2{{template template argument has different template parameters}}
11 f(B
<int>()); // old-error {{no matching function for call}}
12 f(B
<int,float>()); // expected-error {{no matching function for call}}
17 template<typename
> struct match
;
19 template<template<typename
> class t
,typename T
> struct match
<t
<T
>>;
21 template<template<typename
,typename
> class t
,typename T0
,typename T1
>
22 struct match
<t
<T0
,T1
>> {};
24 template<typename
,typename
= void> struct other
{};
25 template struct match
<other
<void,void>>;
29 template<class T1
, class T2
= float> struct A
;
31 template<class T3
> struct B
;
32 template<template<class T4
> class TT1
, class T5
> struct B
<TT1
<T5
>> ;
33 template<template<class T6
, class T7
> class TT2
, class T8
, class T9
> struct B
<TT2
<T8
, T9
>> {};
34 template struct B
<A
<int>>;
38 template<class T1
, int V1
= 1> struct A
;
40 template<class T2
> struct B
;
41 template<template<class T3
> class TT1
, class T4
> struct B
<TT1
<T4
>> ;
42 template<template<class T5
, int V2
> class TT2
, class T6
, int V3
> struct B
<TT2
<T6
, V3
>> {};
43 template struct B
<A
<int>>;
47 template <class T1
> struct A
;
49 template<class T2
, template <class T3
> class T4
= A
> struct B
{};
51 template<class T5
> struct C
;
53 template<template<class T6
> class TT1
, class T7
> struct C
<TT1
<T7
>>;
55 template<template<class T8
, template <class T9
> class> class TT2
,
56 class T10
, template <class T11
> class TT3
>
57 struct C
<TT2
<T10
, TT3
>> {};
59 template struct C
<B
<int>>;
62 namespace class_template
{
63 template <class T1
, class T2
= float> struct A
;
65 template <class T3
> struct B
;
67 template <template <class T4
> class TT1
, class T5
> struct B
<TT1
<T5
>>;
69 template <class T6
, class T7
> struct B
<A
<T6
, T7
>> {};
71 template struct B
<A
<int>>;
72 } // namespace class_template
74 namespace class_template_func
{
75 template <class T1
, class T2
= float> struct A
{};
77 template <template <class T4
> class TT1
, class T5
> void f(TT1
<T5
>);
78 template <class T6
, class T7
> void f(A
<T6
, T7
>) {};
83 } // namespace class_template_func
85 namespace type_pack1
{
86 template<class T2
> struct A
;
87 template<template<class ...T3s
> class TT1
, class T4
> struct A
<TT1
<T4
>> ;
88 template<template<class T5
> class TT2
, class T6
> struct A
<TT2
<T6
>> {};
90 template<class T1
> struct B
;
91 template struct A
<B
<char>>;
92 } // namespace type_pack1
94 namespace type_pack2
{
95 template<class T2
> struct A
;
96 template<template<class ...T3s
> class TT1
, class ...T4
> struct A
<TT1
<T4
...>> ;
97 template<template<class T5
> class TT2
, class ...T6
> struct A
<TT2
<T6
...>> {};
99 template<class T1
> struct B
;
100 template struct A
<B
<char>>;
101 } // namespace type_pack2
103 namespace type_pack3
{
104 template<class T1
, class T2
= float> struct A
;
106 template<class T3
> struct B
;
108 template<template<class T4
> class TT1
, class T5
> struct B
<TT1
<T5
>>;
109 // new-note@-1 {{template is declared here}}
110 template<template<class T6
, class ...T7s
> class TT2
, class T8
, class ...T9s
> struct B
<TT2
<T8
, T9s
...>>;
111 // old-note@-1 {{template is declared here}}
113 template struct B
<A
<int>>;
114 // expected-error@-1 {{explicit instantiation of undefined template}}
115 } // namespace type_pack3
117 namespace gcc_issue
{
118 template<class T1
, class T2
> struct A
;
120 template<template<class T1
> class TT1
, class T2
> struct A
<TT1
<T2
>, typename TT1
<T2
>::type
>;
121 // new-note@-1 {{partial specialization matches}}
123 template<template<class T3
, class T4
> class TT2
, class T5
, class T6
>
124 struct A
<TT2
<T5
, T6
>, typename TT2
<T5
, T5
>::type
>;
125 // new-note@-1 {{partial specialization matches}}
126 // old-note@-2 {{template is declared here}}
128 template <class T7
, class T8
= T7
> struct B
{ using type
= int; };
130 template struct A
<B
<int>, int>;
131 // new-error@-1 {{ambiguous partial specializations}}
132 // old-error@-2 {{explicit instantiation of undefined template}}
133 } // namespace gcc_issue
135 namespace ttp_defaults
{
136 template <template <class T1
> class TT1
> struct A
{};
137 // old-note@-1 2{{previous template template parameter}}
139 template <template <class T2
> class TT2
> void f(A
<TT2
>);
140 // new-note@-1 {{explicit instantiation candidate}}
141 // old-note@-2 {{invalid explicitly-specified argument for template parameter 'TT2'}}
143 // FIXME: The default arguments on the TTP are not available during partial ordering.
144 template <template <class T3
, class T4
= float> class TT3
> void f(A
<TT3
>) {};
145 // new-note@-1 {{explicit instantiation candidate}}
146 // old-error@-2 {{template template argument has different template parameters}}
147 // old-note@-3 {{too many template parameters}}
149 template <class T5
, class T6
= int> struct B
;
150 // old-note@-1 {{too many template parameters}}
152 template void f
<B
>(A
<B
>);
153 // new-error@-1 {{partial ordering for explicit instantiation of 'f' is ambiguous}}
154 // old-error@-2 {{template template argument has different template parameters}}
155 // old-error@-3 {{explicit instantiation of 'f' does not refer to a function template}}
156 } // namespace ttp_defaults
159 template <template <class... > class TT1
> struct A
{ static constexpr int V
= 0; };
160 template <template <class > class TT2
> struct A
<TT2
> { static constexpr int V
= 1; };
161 // new-note@-1 {{partial specialization matches}}
162 template <template <class, class> class TT3
> struct A
<TT3
> { static constexpr int V
= 2; };
163 // new-note@-1 {{partial specialization matches}}
165 template <class ... > struct B
;
166 template <class > struct C
;
167 template <class, class > struct D
;
168 template <class, class, class> struct E
;
170 static_assert(A
<B
>::V
== 0); // new-error {{ambiguous partial specializations}}
171 static_assert(A
<C
>::V
== 1);
172 static_assert(A
<D
>::V
== 2);
173 static_assert(A
<E
>::V
== 0);
174 } // namespace ttp_only
176 namespace consistency
{
177 template<class T
> struct nondeduced
{ using type
= T
; };
178 template<class T8
, class T9
= float> struct B
;
181 template<class T1
, class T2
, class T3
> struct A
;
183 template<template<class, class> class TT1
,
184 class T1
, class T2
, class T3
, class T4
>
185 struct A
<TT1
<T1
, T2
>, TT1
<T3
, T4
>, typename nondeduced
<TT1
<T1
, T2
>>::type
> {};
187 template<template<class> class UU1
,
188 template<class> class UU2
,
190 struct A
<UU1
<U1
>, UU2
<U2
>, typename nondeduced
<UU1
<U1
>>::type
>;
192 template struct A
<B
<int>, B
<int>, B
<int>>;
195 template<class T1
, class T2
, class T3
> struct A
;
197 template<template<class, class> class TT1
,
198 class T1
, class T2
, class T3
, class T4
>
199 struct A
<TT1
<T1
, T2
>, TT1
<T3
, T4
>, typename nondeduced
<TT1
<T1
, T4
>>::type
> {};
200 // new-note@-1 {{partial specialization matches}}
202 template<template<class> class UU1
,
203 template<class> class UU2
,
205 struct A
<UU1
<U1
>, UU2
<U2
>, typename nondeduced
<UU1
<U1
>>::type
>;
206 // new-note@-1 {{partial specialization matches}}
208 template struct A
<B
<int>, B
<int>, B
<int>>;
209 // new-error@-1 {{ambiguous partial specializations}}
212 template<class T1
, class T2
, class T3
> struct A
;
214 template<template<class, class> class TT1
,
215 class T1
, class T2
, class T3
, class T4
>
216 struct A
<TT1
<T1
, T2
>, TT1
<T3
, T4
>, typename nondeduced
<TT1
<T1
, T2
>>::type
> {};
217 // new-note@-1 {{partial specialization matches}}
219 template<template<class> class UU1
,
221 struct A
<UU1
<U1
>, UU1
<U2
>, typename nondeduced
<UU1
<U1
>>::type
>;
222 // new-note@-1 {{partial specialization matches}}
224 template struct A
<B
<int>, B
<int>, B
<int>>;
225 // new-error@-1 {{ambiguous partial specializations}}
228 template<class T1
, class T2
, class T3
> struct A
;
230 template<template<class, class> class TT1
,
231 class T1
, class T2
, class T3
, class T4
>
232 struct A
<TT1
<T1
, T2
>, TT1
<T3
, T4
>, typename nondeduced
<TT1
<T1
, T4
>>::type
> {};
233 // new-note@-1 {{partial specialization matches}}
235 template<template<class> class UU1
,
237 struct A
<UU1
<U1
>, UU1
<U2
>, typename nondeduced
<UU1
<U1
>>::type
>;
238 // new-note@-1 {{partial specialization matches}}
240 template struct A
<B
<int>, B
<int>, B
<int>>;
241 // new-error@-1 {{ambiguous partial specializations}}
244 template<class T1
, class T2
> struct A
;
246 template<template<class, class> class TT1
,
247 class T1
, class T2
, class T3
, class T4
>
248 struct A
<TT1
<T1
, T2
>, TT1
<T3
, T4
>> {};
249 // new-note@-1 {{partial specialization matches}}
251 template<template<class> class UU1
,
253 struct A
<UU1
<U1
>, UU1
<U2
>>;
254 // new-note@-1 {{partial specialization matches}}
256 template struct A
<B
<int>, B
<int>>;
257 // new-error@-1 {{ambiguous partial specializations}}
260 template<class T1
, class T2
> struct A
;
262 template<template<class, class> class TT1
,
263 class T1
, class T2
, class T3
>
264 struct A
<TT1
<T1
, T2
>, TT1
<T1
, T3
>> {};
265 // new-note@-1 {{partial specialization matches}}
267 template<template<class> class UU1
,
269 struct A
<UU1
<U1
>, UU1
<U2
>>;
270 // new-note@-1 {{partial specialization matches}}
272 template struct A
<B
<int>, B
<int>>;
273 // new-error@-1 {{ambiguous partial specializations}}
275 } // namespace consistency
279 template<class T
, class U
> struct A
{};
281 template<template<class> class TT
> auto f(TT
<int> a
) { return a
; }
282 // old-note@-1 2{{template template argument has different template parameters}}
283 // new-note@-2 2{{substitution failure: too few template arguments}}
288 using X
= decltype(f(v1
));
289 // expected-error@-1 {{no matching function for call}}
291 using X
= decltype(f(v2
));
292 // expected-error@-1 {{no matching function for call}}
295 template <class T1
, int E1
> struct A
{
296 static constexpr auto val
= E1
;
298 template <template <class T3
> class TT
> void f(TT
<int> v
) {
299 // old-note@-1 {{template template argument has different template parameters}}
300 // new-note@-2 {{substitution failure: too few template arguments}}
301 static_assert(v
.val
== 3);
305 // expected-error@-1 {{no matching function for call}}
309 template <class T1
, class ...T2s
> struct A
{
310 static constexpr auto val
= sizeof...(T2s
);
313 template <template <class T3
> class TT
> void f(TT
<int> v
) {
314 // old-note@-1 {{template template argument has different template parameters}}
315 // new-note@-2 {{deduced type 'A<[...], (no argument), (no argument), (no argument)>' of 1st parameter does not match adjusted type 'A<[...], void, void, void>' of argument [with TT = A]}}
316 static_assert(v
.val
== 3);
319 f(A
<int, void, void, void>());
320 // expected-error@-1 {{no matching function for call}}
324 template <class T1
, int V1
, int V2
> struct A
{
326 static constexpr int v1
= V1
, v2
= V2
;
329 template <template <class T1
> class TT1
> auto f(TT1
<int>) {
333 template <template <class T2
, int V3
> class TT2
> auto g(TT2
<double, 1>) {
334 // new-note@-1 {{too few template arguments for class template 'A'}}
335 // old-note@-2 {{template template argument has different template parameters}}
336 return f(TT2
<int, 2>());
339 using B
= decltype(g(A
<double, 1, 3>()));
340 // expected-error@-1 {{no matching function for call}}
342 using X
= B::type
; // expected-error {{undeclared identifier 'B'}}
344 static_assert(B::v1
== 2); // expected-error {{undeclared identifier 'B'}}
345 static_assert(B::v2
== 3); // expected-error {{undeclared identifier 'B'}}
347 namespace defaulted
{
348 template <class T1
, class T2
= T1
*> struct A
{
352 template <template <class> class TT
> TT
<float> f(TT
<int>);
353 // new-note@-1 {{deduced type 'A<[...], (default) int *>' of 1st parameter does not match adjusted type 'A<[...], double *>' of argument [with TT = A]}}
354 // old-note@-2 2{{template template argument has different template parameters}}
356 using X
= int*; // new-note {{previous definition is here}}
357 using X
= decltype(f(A
<int>()))::type
;
358 // new-error@-1 {{different types ('decltype(f(A<int>()))::type' (aka 'float *') vs 'int *')}}
359 // old-error@-2 {{no matching function for call}}
362 using Y
= decltype(f(A
<int, double*>()))::type
;
363 // expected-error@-1 {{no matching function for call}}
364 } // namespace defaulted
365 } // namespace classes
367 namespace regression1
{
368 template <typename T
, typename Y
> struct map
{};
369 template <typename T
> class foo
{};
371 template <template <typename
...> class MapType
, typename Value
>
372 Value
bar(MapType
<int, Value
> map
);
374 template <template <typename
...> class MapType
, typename Value
>
375 Value
bar(MapType
<int, foo
<Value
>> map
);
378 map
<int, foo
<int>> input
;
381 } // namespace regression1
383 namespace regression2
{
384 template <class> struct D
{};
386 template <class ET
, template <class> class VT
>
389 template <typename
, int> struct Matrix
;
390 template struct D
<Matrix
<double, 3>>;
391 } // namespace regression2