1 // RUN: %clang_cc1 %s -fsyntax-only -std=c++23 -verify
4 template<class T
, class U
= T
> class B
{};
5 template<template<class> class P
, class T
> void f(P
<T
>);
6 // expected-note@-1 {{deduced type 'B<[...], (default) int>' of 1st parameter does not match adjusted type 'B<[...], float>' of argument [with P = B, T = int]}}
10 f(B
<int,float>()); // expected-error {{no matching function for call}}
15 template<typename
> struct match
;
17 template<template<typename
> class t
,typename T
> struct match
<t
<T
>>;
19 template<template<typename
,typename
> class t
,typename T0
,typename T1
>
20 struct match
<t
<T0
,T1
>> {};
22 template<typename
,typename
= void> struct other
{};
23 template struct match
<other
<void,void>>;
27 template<class T1
, class T2
= float> struct A
;
29 template<class T3
> struct B
;
30 template<template<class T4
> class TT1
, class T5
> struct B
<TT1
<T5
>> ;
31 template<template<class T6
, class T7
> class TT2
, class T8
, class T9
> struct B
<TT2
<T8
, T9
>> {};
32 template struct B
<A
<int>>;
36 template<class T1
, int V1
= 1> struct A
;
38 template<class T2
> struct B
;
39 template<template<class T3
> class TT1
, class T4
> struct B
<TT1
<T4
>> ;
40 template<template<class T5
, int V2
> class TT2
, class T6
, int V3
> struct B
<TT2
<T6
, V3
>> {};
41 template struct B
<A
<int>>;
45 template <class T1
> struct A
;
47 template<class T2
, template <class T3
> class T4
= A
> struct B
{};
49 template<class T5
> struct C
;
51 template<template<class T6
> class TT1
, class T7
> struct C
<TT1
<T7
>>;
53 template<template<class T8
, template <class T9
> class> class TT2
,
54 class T10
, template <class T11
> class TT3
>
55 struct C
<TT2
<T10
, TT3
>> {};
57 template struct C
<B
<int>>;
60 namespace class_template
{
61 template <class T1
, class T2
= float> struct A
;
63 template <class T3
> struct B
;
65 template <template <class T4
> class TT1
, class T5
> struct B
<TT1
<T5
>>;
67 template <class T6
, class T7
> struct B
<A
<T6
, T7
>> {};
69 template struct B
<A
<int>>;
70 } // namespace class_template
72 namespace class_template_func
{
73 template <class T1
, class T2
= float> struct A
{};
75 template <template <class T4
> class TT1
, class T5
> void f(TT1
<T5
>);
76 template <class T6
, class T7
> void f(A
<T6
, T7
>) {};
81 } // namespace class_template_func
83 namespace type_pack1
{
84 template<class T2
> struct A
;
85 template<template<class ...T3s
> class TT1
, class T4
> struct A
<TT1
<T4
>> ;
86 template<template<class T5
> class TT2
, class T6
> struct A
<TT2
<T6
>> {};
88 template<class T1
> struct B
;
89 template struct A
<B
<char>>;
90 } // namespace type_pack1
92 namespace type_pack2
{
93 template<class T2
> struct A
;
94 template<template<class ...T3s
> class TT1
, class ...T4
> struct A
<TT1
<T4
...>> ;
95 template<template<class T5
> class TT2
, class ...T6
> struct A
<TT2
<T6
...>> {};
97 template<class T1
> struct B
;
98 template struct A
<B
<char>>;
99 } // namespace type_pack2
101 namespace type_pack3
{
102 template<class T1
, class T2
= float> struct A
;
104 template<class T3
> struct B
;
106 template<template<class T4
> class TT1
, class T5
> struct B
<TT1
<T5
>>;
108 template<template<class T6
, class ...T7s
> class TT2
, class T8
, class ...T9s
> struct B
<TT2
<T8
, T9s
...>> {};
110 template struct B
<A
<int>>;
111 } // namespace type_pack3
113 namespace gcc_issue
{
114 template<class T1
, class T2
> struct A
;
116 template<template<class T1
> class TT1
, class T2
> struct A
<TT1
<T2
>, typename TT1
<T2
>::type
>;
117 // expected-note@-1 {{partial specialization matches}}
119 template<template<class T3
, class T4
> class TT2
, class T5
, class T6
>
120 struct A
<TT2
<T5
, T6
>, typename TT2
<T5
, T5
>::type
>;
121 // expected-note@-1 {{partial specialization matches}}
123 template <class T7
, class T8
= T7
> struct B
{ using type
= int; };
125 template struct A
<B
<int>, int>;
126 // expected-error@-1 {{ambiguous partial specializations}}
127 } // namespace gcc_issue
129 namespace ttp_defaults
{
130 template <template <class T1
> class TT1
> struct A
{};
132 template <template <class T2
> class TT2
> void f(A
<TT2
>);
133 // expected-note@-1 {{explicit instantiation candidate}}
135 // FIXME: The default arguments on the TTP are not available during partial ordering.
136 template <template <class T3
, class T4
= float> class TT3
> void f(A
<TT3
>) {};
137 // expected-note@-1 {{explicit instantiation candidate}}
139 template <class T5
, class T6
= int> struct B
;
141 template void f
<B
>(A
<B
>);
142 // expected-error@-1 {{partial ordering for explicit instantiation of 'f' is ambiguous}}
143 } // namespace ttp_defaults
146 template <template <class... > class TT1
> struct A
{ static constexpr int V
= 0; };
147 template <template <class > class TT2
> struct A
<TT2
> { static constexpr int V
= 1; };
148 template <template <class, class> class TT3
> struct A
<TT3
> { static constexpr int V
= 2; };
150 template <class ... > struct B
;
151 template <class > struct C
;
152 template <class, class > struct D
;
153 template <class, class, class> struct E
;
155 static_assert(A
<B
>::V
== 0);
156 static_assert(A
<C
>::V
== 1);
157 static_assert(A
<D
>::V
== 2);
158 static_assert(A
<E
>::V
== 0);
159 } // namespace ttp_only
161 namespace consistency
{
162 template<class T
> struct nondeduced
{ using type
= T
; };
163 template<class T8
, class T9
= float> struct B
;
166 template<class T1
, class T2
, class T3
> struct A
;
168 template<template<class, class> class TT1
,
169 class T1
, class T2
, class T3
, class T4
>
170 struct A
<TT1
<T1
, T2
>, TT1
<T3
, T4
>, typename nondeduced
<TT1
<T1
, T2
>>::type
> {};
172 template<template<class> class UU1
,
173 template<class> class UU2
,
175 struct A
<UU1
<U1
>, UU2
<U2
>, typename nondeduced
<UU1
<U1
>>::type
>;
177 template struct A
<B
<int>, B
<int>, B
<int>>;
180 template<class T1
, class T2
, class T3
> struct A
;
182 template<template<class, class> class TT1
,
183 class T1
, class T2
, class T3
, class T4
>
184 struct A
<TT1
<T1
, T2
>, TT1
<T3
, T4
>, typename nondeduced
<TT1
<T1
, T4
>>::type
> {};
185 // expected-note@-1 {{partial specialization matches}}
187 template<template<class> class UU1
,
188 template<class> class UU2
,
190 struct A
<UU1
<U1
>, UU2
<U2
>, typename nondeduced
<UU1
<U1
>>::type
>;
191 // expected-note@-1 {{partial specialization matches}}
193 template struct A
<B
<int>, B
<int>, B
<int>>;
194 // expected-error@-1 {{ambiguous partial specializations}}
197 template<class T1
, class T2
, class T3
> struct A
;
199 template<template<class, class> class TT1
,
200 class T1
, class T2
, class T3
, class T4
>
201 struct A
<TT1
<T1
, T2
>, TT1
<T3
, T4
>, typename nondeduced
<TT1
<T1
, T2
>>::type
> {};
202 // expected-note@-1 {{partial specialization matches}}
204 template<template<class> class UU1
,
206 struct A
<UU1
<U1
>, UU1
<U2
>, typename nondeduced
<UU1
<U1
>>::type
>;
207 // expected-note@-1 {{partial specialization matches}}
209 template struct A
<B
<int>, B
<int>, B
<int>>;
210 // expected-error@-1 {{ambiguous partial specializations}}
213 template<class T1
, class T2
, class T3
> struct A
;
215 template<template<class, class> class TT1
,
216 class T1
, class T2
, class T3
, class T4
>
217 struct A
<TT1
<T1
, T2
>, TT1
<T3
, T4
>, typename nondeduced
<TT1
<T1
, T4
>>::type
> {};
218 // expected-note@-1 {{partial specialization matches}}
220 template<template<class> class UU1
,
222 struct A
<UU1
<U1
>, UU1
<U2
>, typename nondeduced
<UU1
<U1
>>::type
>;
223 // expected-note@-1 {{partial specialization matches}}
225 template struct A
<B
<int>, B
<int>, B
<int>>;
226 // expected-error@-1 {{ambiguous partial specializations}}
229 template<class T1
, class T2
> struct A
;
231 template<template<class, class> class TT1
,
232 class T1
, class T2
, class T3
, class T4
>
233 struct A
<TT1
<T1
, T2
>, TT1
<T3
, T4
>> {};
234 // expected-note@-1 {{partial specialization matches}}
236 template<template<class> class UU1
,
238 struct A
<UU1
<U1
>, UU1
<U2
>>;
239 // expected-note@-1 {{partial specialization matches}}
241 template struct A
<B
<int>, B
<int>>;
242 // expected-error@-1 {{ambiguous partial specializations}}
245 template<class T1
, class T2
> struct A
;
247 template<template<class, class> class TT1
,
248 class T1
, class T2
, class T3
>
249 struct A
<TT1
<T1
, T2
>, TT1
<T1
, T3
>> {};
250 // expected-note@-1 {{partial specialization matches}}
252 template<template<class> class UU1
,
254 struct A
<UU1
<U1
>, UU1
<U2
>>;
255 // expected-note@-1 {{partial specialization matches}}
257 template struct A
<B
<int>, B
<int>>;
258 // expected-error@-1 {{ambiguous partial specializations}}
260 } // namespace consistency
264 template<class T
, class U
> struct A
{};
266 template<template<class> class TT
> auto f(TT
<int> a
) { return a
; }
267 // expected-note@-1 2{{substitution failure: too few template arguments}}
272 using X
= decltype(f(v1
));
273 // expected-error@-1 {{no matching function for call}}
275 using X
= decltype(f(v2
));
276 // expected-error@-1 {{no matching function for call}}
279 template <class T1
, int E1
> struct A
{
280 static constexpr auto val
= E1
;
282 template <template <class T3
> class TT
> void f(TT
<int> v
) {
283 // expected-note@-1 {{substitution failure: too few template arguments}}
284 static_assert(v
.val
== 3);
288 // expected-error@-1 {{no matching function for call}}
292 template <class T1
, class ...T2s
> struct A
{
293 static constexpr auto val
= sizeof...(T2s
);
296 template <template <class T3
> class TT
> void f(TT
<int> v
) {
297 // expected-note@-1 {{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]}}
298 static_assert(v
.val
== 3);
301 f(A
<int, void, void, void>());
302 // expected-error@-1 {{no matching function for call}}
306 template <class T1
, int V1
, int V2
> struct A
{
308 static constexpr int v1
= V1
, v2
= V2
;
311 template <template <class T1
> class TT1
> auto f(TT1
<int>) {
315 template <template <class T2
, int V3
> class TT2
> auto g(TT2
<double, 1>) {
316 // expected-note@-1 {{too few template arguments for class template 'A'}}
317 return f(TT2
<int, 2>());
320 using B
= decltype(g(A
<double, 1, 3>()));
321 // expected-error@-1 {{no matching function for call}}
323 using X
= B::type
; // expected-error {{undeclared identifier 'B'}}
325 static_assert(B::v1
== 2); // expected-error {{undeclared identifier 'B'}}
326 static_assert(B::v2
== 3); // expected-error {{undeclared identifier 'B'}}
328 namespace defaulted
{
329 template <class T1
, class T2
= T1
*> struct A
{
333 template <template <class> class TT
> TT
<float> f(TT
<int>);
334 // expected-note@-1 {{deduced type 'A<[...], (default) int *>' of 1st parameter does not match adjusted type 'A<[...], double *>' of argument [with TT = A]}}
336 using X
= int*; // expected-note {{previous definition is here}}
337 using X
= decltype(f(A
<int>()))::type
;
338 // expected-error@-1 {{different types ('decltype(f(A<int>()))::type' (aka 'float *') vs 'int *')}}
341 using Y
= decltype(f(A
<int, double*>()))::type
;
342 // expected-error@-1 {{no matching function for call}}
343 } // namespace defaulted
344 } // namespace classes
348 template<template<int, int...> class> struct A
{};
349 // expected-error@-1 {{non-type parameter of template template parameter cannot be narrowed from type 'int' to 'char'}}
350 // expected-note@-2 {{previous template template parameter is here}}
352 template<char> struct B
;
353 template struct A
<B
>;
354 // expected-note@-1 {{has different template parameters}}
357 template<template<char, int...> class> struct A
{};
358 template<int> struct B
;
359 template struct A
<B
>;
362 template<template<int...> class> struct A
{};
363 // expected-error@-1 {{non-type parameter of template template parameter cannot be narrowed from type 'int' to 'char'}}
364 // expected-note@-2 {{previous template template parameter is here}}
366 template<char> struct B
;
367 template struct A
<B
>;
368 // expected-note@-1 {{has different template parameters}}
371 template<template<char...> class> struct A
{};
372 template<int> struct B
;
373 template struct A
<B
>;
377 namespace fun_tmpl_call
{
378 namespace match_func
{
379 template <template <class> class TT
> void f(TT
<int>) {};
380 template <class...> struct A
{};
381 void test() { f(A
<int>()); }
382 } // namespace match_func
383 namespace order_func_nonpack
{
384 template <template <class> class TT
> void f(TT
<int>) {}
385 template <template <class...> class TT
> void f(TT
<int>) = delete;
387 template <class> struct A
{};
388 void test() { f(A
<int>()); }
389 } // namespace order_func_nonpack
390 namespace order_func_pack
{
391 template <template <class> class TT
> void f(TT
<int>) = delete;
392 template <template <class...> class TT
> void f(TT
<int>) {}
393 template <class...> struct A
{};
394 void test() { f(A
<int>()); }
395 } // namespace order_func_pack
396 namespace match_enum
{
398 template<template<A
> class TT1
> void f(TT1
<{}>) {}
399 template<int> struct B
{};
400 template void f
<B
>(B
<{}>);
401 } // namespace match_enum
402 namespace match_method
{
404 template <template <class> class TT
> void f(TT
<int>) {};
406 template <class...> struct B
{};
407 void test() { A().f(B
<int>()); }
408 } // namespace match_method
409 namespace order_method_nonpack
{
411 template <template <class> class TT
> void f(TT
<int>) {}
412 template <template <class...> class TT
> void f(TT
<int>) = delete;
414 template <class> struct B
{};
415 void test() { A().f(B
<int>()); }
416 } // namespace order_method_nonpack
417 namespace order_method_pack
{
419 template <template <class> class TT
> void f(TT
<int>) = delete;
420 template <template <class...> class TT
> void f(TT
<int>) {}
422 template <class...> struct B
{};
423 void test() { A().f(B
<int>()); }
424 } // namespace order_method_pack
425 namespace match_conv
{
427 template <template <class> class TT
> operator TT
<int>() { return {}; }
429 template <class...> struct B
{};
430 void test() { B
<int> b
= A(); }
431 } // namespace match_conv
432 namespace order_conv_nonpack
{
434 template <template <class> class TT
> operator TT
<int>() { return {}; };
435 template <template <class...> class TT
> operator TT
<int>() = delete;
437 template <class> struct B
{};
438 void test() { B
<int> b
= A(); }
439 } // namespace order_conv_nonpack
440 namespace order_conv_pack
{
442 template <template <class> class TT
> operator TT
<int>() = delete;
443 template <template <class...> class TT
> operator TT
<int>() { return {}; }
445 template <class...> struct B
{};
446 void test() { B
<int> b
= A(); }
447 } // namespace order_conv_pack
448 namespace regression1
{
449 template <template <class, class...> class TT
, class T1
, class... T2s
>
450 void f(TT
<T1
, T2s
...>) {}
451 template <class> struct A
{};
452 void test() { f(A
<int>()); }
453 } // namespace regression1
454 } // namespace fun_tmpl_packs
458 template<template<class... T1s
> class TT1
> struct A
{};
460 template<template<class T2
> class TT2
> struct A
<TT2
>;
462 template<class... T3s
> struct B
;
463 template struct A
<B
>;
466 template<template<class... T1s
> class TT1
> struct A
;
468 template<template<class T2
> class TT2
> struct A
<TT2
> {};
470 template<class T3
> struct B
;
471 template struct A
<B
>;
474 } // namespace partial
476 namespace regression1
{
477 template <typename T
, typename Y
> struct map
{};
478 template <typename T
> class foo
{};
480 template <template <typename
...> class MapType
, typename Value
>
481 Value
bar(MapType
<int, Value
> map
);
483 template <template <typename
...> class MapType
, typename Value
>
484 Value
bar(MapType
<int, foo
<Value
>> map
);
487 map
<int, foo
<int>> input
;
490 } // namespace regression1
492 namespace constraints
{
493 template <class T
> concept C1
= true;
494 // expected-note@-1 {{similar constraint expression here}}
495 // expected-note@-2 2{{similar constraint expressions not considered equivalent}}
497 template <class T
> concept C2
= C1
<T
> && true;
498 // expected-note@-1 2{{similar constraint expression here}}
500 template <class T
> concept D1
= true;
501 // expected-note@-1 {{similar constraint expressions not considered equivalent}}
504 template<template<C1
, class... T1s
> class TT1
> // expected-note {{TT1' declared here}}
506 template<D1
, class T2
> struct B
{}; // expected-note {{'B' declared here}}
507 template struct A
<B
>;
508 // expected-error@-1 {{'B' is more constrained than template template parameter 'TT1'}}
511 template<template<C2
, class... T1s
> class TT1
> struct A
{};
512 template<C1
, class T2
> struct B
{};
513 template struct A
<B
>;
516 template<template<C1
, class... T1s
> class TT1
> // expected-note {{'TT1' declared here}}
518 template<C2
, class T2
> struct B
{}; // expected-note {{'B' declared here}}
519 template struct A
<B
>;
520 // expected-error@-1 {{'B' is more constrained than template template parameter 'TT1'}}
523 // FIXME: This should be accepted.
524 template<template<C1
... T1s
> class TT1
> // expected-note {{'TT1' declared here}}
526 template<C1 T2
> struct B
{}; // expected-note {{'B' declared here}}
527 template struct A
<B
>;
528 // expected-error@-1 {{'B' is more constrained than template template parameter 'TT1'}}
531 // FIXME: This should be accepted
532 template<template<C2
... T1s
> class TT1
> // expected-note {{'TT1' declared here}}
534 template<C1 T2
> struct B
{}; // expected-note {{'B' declared here}}
535 template struct A
<B
>;
536 // expected-error@-1 {{'B' is more constrained than template template parameter 'TT1'}}
539 template<template<C1
... T1s
> class TT1
> // expected-note {{'TT1' declared here}}
541 template<C2 T2
> struct B
{}; // expected-note {{'B' declared here}}
542 template struct A
<B
>;
543 // expected-error@-1 {{'B' is more constrained than template template parameter 'TT1'}}
546 template<template<class... T1s
> class TT1
>
548 template<C1 T2
> struct B
{};
549 template struct A
<B
>;
552 template<template<C1
... T1s
> class TT1
>
554 template<class T2
> struct B
{};
555 template struct A
<B
>;
558 template<template<C1
... T1s
> class TT1
> // expected-note {{'TT1' declared here}}
560 template<D1 T2
> struct B
{}; // expected-note {{'B' declared here}}
561 template struct A
<B
>;
562 // expected-error@-1 {{'B' is more constrained than template template parameter 'TT1'}}
565 template<template<class...> requires C1
<int> class TT1
> // expected-note {{'TT1' declared here}}
568 template<class> requires C2
<int> struct B
{}; // expected-note {{'B' declared here}}
569 template struct A
<B
>;
570 // expected-error@-1 {{'B' is more constrained than template template parameter 'TT1'}}
573 template<template<class...> requires C2
<int> class TT1
> struct A
{};
574 template<class> requires C1
<int> struct B
{};
575 template struct A
<B
>;
577 } // namespace constraints
579 namespace regression2
{
580 template <class> struct D
{};
582 template <class ET
, template <class> class VT
>
585 template <typename
, int> struct Matrix
;
586 template struct D
<Matrix
<double, 3>>;
587 } // namespace regression2
589 namespace nttp_auto
{
591 template <template <auto... Va
> class TT
> struct A
{};
592 template <int Vi
, short Vs
> struct B
;
593 template struct A
<B
>;
596 // FIXME: Shouldn't accept parameters after a parameter pack.
597 template<template<auto... Va1
, auto Va2
> class> struct A
{};
598 // expected-error@-1 {{deduced non-type template argument does not have the same type as the corresponding template parameter ('auto' vs 'int')}}
599 // expected-note@-2 {{previous template template parameter is here}}
600 template<int... Vi
> struct B
;
601 // expected-note@-1 {{template parameter is declared here}}
602 template struct A
<B
>;
603 // expected-note@-1 {{different template parameters}}
606 // FIXME: Shouldn't accept parameters after a parameter pack.
607 template<template<auto... Va1
, auto... Va2
> class> struct A
{};
608 // expected-error@-1 {{deduced non-type template argument does not have the same type as the corresponding template parameter ('auto' vs 'int')}}
609 // expected-note@-2 {{previous template template parameter is here}}
610 template<int... Vi
> struct B
;
611 // expected-note@-1 {{template parameter is declared here}}
612 template struct A
<B
>;
613 // expected-note@-1 {{different template parameters}}
615 } // namespace nttp_auto
617 namespace nttp_partial_order
{
619 template<template<short> class TT1
> void f(TT1
<0>);
620 template<template<int> class TT2
> void f(TT2
<0>) {}
621 template<int> struct B
{};
622 template void f
<B
>(B
<0>);
626 template<template<A
&> class TT1
> void f(TT1
<a
>);
627 template<template<const A
&> class TT2
> void f(TT2
<a
>) {}
628 template<const A
&> struct B
{};
629 template void f
<B
>(B
<a
>);
633 template<template<A
> class TT1
> void f(TT1
<{}>);
634 template<template<int> class TT2
> void f(TT2
<{}>) {}
635 template<int> struct B
{};
636 template void f
<B
>(B
<{}>);
640 template<template<A
*> class TT1
> void f(TT1
<&a
>);
641 template<template<const A
*> class TT2
> void f(TT2
<&a
>) {}
642 template<const A
*> struct B
{};
643 template void f
<B
>(B
<&a
>);
647 template<template<int A::*> class TT1
> void f(TT1
<&A::m
>);
648 template<template<const int A::*> class TT2
> void f(TT2
<&A::m
>) {}
649 template<const int A::*> struct B
{};
650 template void f
<B
>(B
<&A::m
>);
654 using nullptr_t
= decltype(nullptr);
655 template<template<nullptr_t
> class TT2
> void f(TT2
<nullptr>);
656 template<template<A
*> class TT1
> void f(TT1
<nullptr>) {}
657 template<A
*> struct B
{};
658 template void f
<B
>(B
<nullptr>);
660 } // namespace nttp_partial_order