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