xref: /llvm-project/clang/test/SemaTemplate/cwg2398.cpp (revision 8a334af417ff2ef49e0bc74f9421b4f3aa479805)
1 // RUN: %clang_cc1 %s -fsyntax-only -std=c++23 -verify
2 
3 namespace issue1 {
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]}}
7 
8   void g() {
9     f(B<int>());
10     f(B<int,float>()); // expected-error {{no matching function for call}}
11   }
12 } // namespace issue1
13 
14 namespace issue2 {
15   template<typename> struct match;
16 
17   template<template<typename> class t,typename T> struct match<t<T>>;
18 
19   template<template<typename,typename> class t,typename T0,typename T1>
20   struct match<t<T0,T1>> {};
21 
22   template<typename,typename = void> struct other {};
23   template struct match<other<void,void>>;
24 } // namespace issue2
25 
26 namespace type {
27   template<class T1, class T2 = float> struct A;
28 
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>>;
33 } // namespace type
34 
35 namespace value {
36   template<class T1, int V1 = 1> struct A;
37 
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>>;
42 } // namespace value
43 
44 namespace templ {
45   template <class T1> struct A;
46 
47   template<class T2, template <class T3> class T4 = A> struct B {};
48 
49   template<class T5> struct C;
50 
51   template<template<class T6> class TT1, class T7> struct C<TT1<T7>>;
52 
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>> {};
56 
57   template struct C<B<int>>;
58 } // namespace templ
59 
60 namespace class_template {
61   template <class T1, class T2 = float> struct A;
62 
63   template <class T3> struct B;
64 
65   template <template <class T4> class TT1, class T5> struct B<TT1<T5>>;
66 
67   template <class T6, class T7> struct B<A<T6, T7>> {};
68 
69   template struct B<A<int>>;
70 } // namespace class_template
71 
72 namespace class_template_func {
73   template <class T1, class T2 = float> struct A {};
74 
75   template <template <class T4> class TT1, class T5> void f(TT1<T5>);
76   template <class T6, class T7>                      void f(A<T6, T7>) {};
77 
78   void g() {
79     f(A<int>());
80   }
81 } // namespace class_template_func
82 
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>> {};
87 
88   template<class T1> struct B;
89   template struct A<B<char>>;
90 } // namespace type_pack1
91 
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...>> {};
96 
97   template<class T1> struct B;
98   template struct A<B<char>>;
99 } // namespace type_pack2
100 
101 namespace type_pack3 {
102   template<class T1, class T2 = float> struct A;
103 
104   template<class T3> struct B;
105 
106   template<template<class T4              > class TT1, class T5              > struct B<TT1<T5        >>;
107 
108   template<template<class T6, class ...T7s> class TT2, class T8, class ...T9s> struct B<TT2<T8, T9s...>> {};
109 
110   template struct B<A<int>>;
111 } // namespace type_pack3
112 
113 namespace gcc_issue {
114   template<class T1, class T2> struct A;
115 
116   template<template<class T1> class TT1, class T2> struct A<TT1<T2>, typename TT1<T2>::type>;
117   // expected-note@-1 {{partial specialization matches}}
118 
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}}
122 
123   template <class T7, class T8 = T7> struct B { using type = int; };
124 
125   template struct A<B<int>, int>;
126   // expected-error@-1 {{ambiguous partial specializations}}
127 } // namespace gcc_issue
128 
129 namespace ttp_defaults {
130   template <template <class T1> class TT1> struct A {};
131 
132   template <template <class T2> class TT2> void f(A<TT2>);
133   // expected-note@-1 {{explicit instantiation candidate}}
134 
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}}
138 
139   template <class T5, class T6 = int> struct B;
140 
141   template void f<B>(A<B>);
142   // expected-error@-1 {{partial ordering for explicit instantiation of 'f' is ambiguous}}
143 } // namespace ttp_defaults
144 
145 namespace ttp_only {
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; };
149 
150   template <class ...          > struct B;
151   template <class              > struct C;
152   template <class, class       > struct D;
153   template <class, class, class> struct E;
154 
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
160 
161 namespace consistency {
162   template<class T> struct nondeduced { using type = T; };
163   template<class T8, class T9 = float> struct B;
164 
165   namespace t1 {
166     template<class T1, class T2, class T3> struct A;
167 
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> {};
171 
172     template<template<class> class UU1,
173              template<class> class UU2,
174              class U1, class U2>
175     struct A<UU1<U1>, UU2<U2>, typename nondeduced<UU1<U1>>::type>;
176 
177     template struct A<B<int>, B<int>, B<int>>;
178   } // namespace t1
179   namespace t2 {
180     template<class T1, class T2, class T3> struct A;
181 
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}}
186 
187     template<template<class> class UU1,
188              template<class> class UU2,
189              class U1, class U2>
190     struct A<UU1<U1>, UU2<U2>, typename nondeduced<UU1<U1>>::type>;
191     // expected-note@-1 {{partial specialization matches}}
192 
193     template struct A<B<int>, B<int>, B<int>>;
194     // expected-error@-1 {{ambiguous partial specializations}}
195   } // namespace t2
196   namespace t3 {
197     template<class T1, class T2, class T3> struct A;
198 
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}}
203 
204     template<template<class> class UU1,
205              class U1, class U2>
206     struct A<UU1<U1>, UU1<U2>, typename nondeduced<UU1<U1>>::type>;
207     // expected-note@-1 {{partial specialization matches}}
208 
209     template struct A<B<int>, B<int>, B<int>>;
210     // expected-error@-1 {{ambiguous partial specializations}}
211   } // namespace t3
212   namespace t4 {
213     template<class T1, class T2, class T3> struct A;
214 
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}}
219 
220     template<template<class> class UU1,
221              class U1, class U2>
222     struct A<UU1<U1>, UU1<U2>, typename nondeduced<UU1<U1>>::type>;
223     // expected-note@-1 {{partial specialization matches}}
224 
225     template struct A<B<int>, B<int>, B<int>>;
226     // expected-error@-1 {{ambiguous partial specializations}}
227   } // namespace t4
228   namespace t5 {
229     template<class T1, class T2> struct A;
230 
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}}
235 
236     template<template<class> class UU1,
237              class U1, class U2>
238     struct A<UU1<U1>, UU1<U2>>;
239     // expected-note@-1 {{partial specialization matches}}
240 
241     template struct A<B<int>, B<int>>;
242     // expected-error@-1 {{ambiguous partial specializations}}
243   } // namespace t5
244   namespace t6 {
245     template<class T1, class T2> struct A;
246 
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}}
251 
252     template<template<class> class UU1,
253              class U1, class U2>
254     struct A<UU1<U1>, UU1<U2>>;
255     // expected-note@-1 {{partial specialization matches}}
256 
257     template struct A<B<int>, B<int>>;
258     // expected-error@-1 {{ambiguous partial specializations}}
259   } // namespace t6
260 } // namespace consistency
261 
262 namespace classes {
263   namespace canon {
264     template<class T, class U> struct A {};
265 
266     template<template<class> class TT> auto f(TT<int> a) { return a; }
267     // expected-note@-1 2{{substitution failure: too few template arguments}}
268 
269     A<int, float> v1;
270     A<int, double> v2;
271 
272     using X = decltype(f(v1));
273     // expected-error@-1 {{no matching function for call}}
274 
275     using X = decltype(f(v2));
276     // expected-error@-1 {{no matching function for call}}
277   } // namespace canon
278   namespace expr {
279     template <class T1, int E1> struct A {
280       static constexpr auto val = E1;
281     };
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);
285     };
286     void test() {
287       f(A<int, 3>());
288       // expected-error@-1 {{no matching function for call}}
289     }
290   } // namespace expr
291   namespace packs {
292     template <class T1, class ...T2s> struct A {
293       static constexpr auto val = sizeof...(T2s);
294     };
295 
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);
299     };
300     void test() {
301       f(A<int, void, void, void>());
302       // expected-error@-1 {{no matching function for call}}
303     }
304   } // namespace packs
305   namespace nested {
306     template <class T1, int V1, int V2> struct A {
307       using type = T1;
308       static constexpr int v1 = V1, v2 = V2;
309     };
310 
311     template <template <class T1> class TT1> auto f(TT1<int>) {
312       return TT1<float>();
313     }
314 
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>());
318     }
319 
320     using B = decltype(g(A<double, 1, 3>()));
321     // expected-error@-1 {{no matching function for call}}
322 
323     using X = B::type; // expected-error {{undeclared identifier 'B'}}
324     using X = float;
325     static_assert(B::v1 == 2); // expected-error {{undeclared identifier 'B'}}
326     static_assert(B::v2 == 3); // expected-error {{undeclared identifier 'B'}}
327   }
328   namespace defaulted {
329     template <class T1, class T2 = T1*> struct A {
330       using type = T2;
331     };
332 
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]}}
335 
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 *')}}
339 
340     using Y = double*;
341     using Y = decltype(f(A<int, double*>()))::type;
342     // expected-error@-1 {{no matching function for call}}
343   } // namespace defaulted
344 } // namespace classes
345 
346 namespace packs {
347   namespace t1 {
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}}
351 
352     template<char> struct B;
353     template struct A<B>;
354     // expected-note@-1 {{has different template parameters}}
355   } // namespace t1
356   namespace t2 {
357     template<template<char, int...> class> struct A {};
358     template<int> struct B;
359     template struct A<B>;
360   } // namespace t2
361   namespace t3 {
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}}
365 
366     template<char> struct B;
367     template struct A<B>;
368     // expected-note@-1 {{has different template parameters}}
369   } // namespace t3
370   namespace t4 {
371     template<template<char...> class> struct A {};
372     template<int> struct B;
373     template struct A<B>;
374   } // namespace t4
375 } // namespace packs
376 
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;
386 
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 {
397     enum A {};
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 {
403     struct A {
404       template <template <class> class TT> void f(TT<int>) {};
405     };
406     template <class...> struct B {};
407     void test() { A().f(B<int>()); }
408   } // namespace match_method
409   namespace order_method_nonpack {
410     struct A {
411       template <template <class> class TT> void f(TT<int>) {}
412       template <template <class...> class TT> void f(TT<int>) = delete;
413     };
414     template <class> struct B {};
415     void test() { A().f(B<int>()); }
416   } // namespace order_method_nonpack
417   namespace order_method_pack {
418     struct A {
419       template <template <class> class TT> void f(TT<int>) = delete;
420       template <template <class...> class TT> void f(TT<int>) {}
421     };
422     template <class...> struct B {};
423     void test() { A().f(B<int>()); }
424   } // namespace order_method_pack
425   namespace match_conv {
426     struct A {
427       template <template <class> class TT> operator TT<int>() { return {}; }
428     };
429     template <class...> struct B {};
430     void test() { B<int> b = A(); }
431   } // namespace match_conv
432   namespace order_conv_nonpack {
433     struct A {
434       template <template <class> class TT> operator TT<int>() { return {}; };
435       template <template <class...> class TT> operator TT<int>() = delete;
436     };
437     template <class> struct B {};
438     void test() { B<int> b = A(); }
439   } // namespace order_conv_nonpack
440   namespace order_conv_pack {
441     struct A {
442       template <template <class> class TT> operator TT<int>() = delete;
443       template <template <class...> class TT> operator TT<int>() { return {}; }
444     };
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
455 
456 namespace partial {
457   namespace t1 {
458     template<template<class... T1s> class TT1> struct A {};
459 
460     template<template<class T2> class TT2> struct A<TT2>;
461 
462     template<class... T3s> struct B;
463     template struct A<B>;
464   } // namespace t1
465   namespace t2 {
466     template<template<class... T1s> class TT1> struct A;
467 
468     template<template<class T2> class TT2> struct A<TT2> {};
469 
470     template<class T3> struct B;
471     template struct A<B>;
472   } // namespace t1
473 
474 } // namespace partial
475 
476 namespace regression1 {
477   template <typename T, typename Y> struct map {};
478   template <typename T> class foo {};
479 
480   template <template <typename...> class MapType, typename Value>
481   Value bar(MapType<int, Value> map);
482 
483   template <template <typename...> class MapType, typename Value>
484   Value bar(MapType<int, foo<Value>> map);
485 
486   void aux() {
487     map<int, foo<int>> input;
488     bar(input);
489   }
490 } // namespace regression1
491 
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}}
496 
497   template <class T> concept C2 = C1<T> && true;
498   // expected-note@-1 2{{similar constraint expression here}}
499 
500   template <class T> concept D1 = true;
501   // expected-note@-1 {{similar constraint expressions not considered equivalent}}
502 
503   namespace t1 {
504     template<template<C1, class... T1s> class TT1> // expected-note {{TT1' declared here}}
505     struct A {};
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'}}
509   } // namespace t1
510   namespace t2 {
511     template<template<C2, class... T1s> class TT1> struct A {};
512     template<C1, class T2> struct B {};
513     template struct A<B>;
514   } // namespace t2
515   namespace t3 {
516     template<template<C1, class... T1s> class TT1> // expected-note {{'TT1' declared here}}
517     struct A {};
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'}}
521   } // namespace t2
522   namespace t4 {
523     // FIXME: This should be accepted.
524     template<template<C1... T1s> class TT1> // expected-note {{'TT1' declared here}}
525     struct A {};
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'}}
529   } // namespace t4
530   namespace t5 {
531     // FIXME: This should be accepted
532     template<template<C2... T1s> class TT1> // expected-note {{'TT1' declared here}}
533     struct A {};
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'}}
537   } // namespace t5
538   namespace t6 {
539     template<template<C1... T1s> class TT1> // expected-note {{'TT1' declared here}}
540     struct A {};
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'}}
544   } // namespace t6
545   namespace t7 {
546     template<template<class... T1s> class TT1>
547     struct A {};
548     template<C1 T2> struct B {};
549     template struct A<B>;
550   } // namespace t7
551   namespace t8 {
552     template<template<C1... T1s> class TT1>
553     struct A {};
554     template<class T2> struct B {};
555     template struct A<B>;
556   } // namespace t8
557   namespace t9 {
558     template<template<C1... T1s> class TT1> // expected-note {{'TT1' declared here}}
559     struct A {};
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'}}
563   } // namespace t9
564   namespace t10 {
565     template<template<class...> requires C1<int> class TT1> // expected-note {{'TT1' declared here}}
566     struct A {};
567 
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'}}
571   } // namespace t10
572   namespace t11 {
573     template<template<class...> requires C2<int> class TT1> struct A {};
574     template<class> requires C1<int> struct B {};
575     template struct A<B>;
576   } // namespace t11
577 } // namespace constraints
578 
579 namespace regression2 {
580   template <class> struct D {};
581 
582   template <class ET, template <class> class VT>
583   struct D<VT<ET>>;
584 
585   template <typename, int> struct Matrix;
586   template struct D<Matrix<double, 3>>;
587 } // namespace regression2
588 
589 namespace nttp_auto {
590   namespace t1 {
591     template <template <auto... Va> class TT> struct A {};
592     template <int Vi, short Vs> struct B;
593     template struct A<B>;
594   } // namespace t1
595   namespace t2 {
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}}
604   } // namespace t2
605   namespace t3 {
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}}
614   } // namespace t3
615 } // namespace nttp_auto
616 
617 namespace nttp_partial_order {
618   namespace t1 {
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>);
623   } // namespace t1
624   namespace t2 {
625     struct A {} a;
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>);
630   } // namespace t2
631   namespace t3 {
632     enum 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<{}>);
637   } // namespace t3
638   namespace t4 {
639     struct A {} a;
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>);
644   } // namespace t4
645   namespace t5 {
646     struct A { int m; };
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>);
651   } // namespace t5
652   namespace t6 {
653     struct A {};
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>);
659   } // namespace t6
660 } // namespace nttp_partial_order
661