brintos

brintos / llvm-project-archived public Read only

0
0
Text · 23.3 KiB · a209615 Raw
726 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++112// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++173// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++234 5// Template argument deduction with template template parameters.6template<typename T, template<T> class A>7struct X0 {8  static const unsigned value = 0;9};10 11template<template<int> class A>12struct X0<int, A> {13  static const unsigned value = 1;14};15 16template<class T>17struct type_identity {18    using type = T;19};20 21template<class T>22using type_identity_t = typename type_identity<T>::type;23 24template <typename... T>25struct args_tag {};26 27template<int> struct X0i;28template<long> struct X0l;29int array_x0a[X0<long, X0l>::value == 0? 1 : -1];30int array_x0b[X0<int, X0i>::value == 1? 1 : -1];31 32template<typename T, typename U>33struct is_same {34  static const bool value = false;35};36 37template<typename T>38struct is_same<T, T> {39  static const bool value = true;40};41 42template<typename T> struct allocator { };43template<typename T, typename Alloc = allocator<T> > struct vector {};44 45// Fun with meta-lambdas!46struct _1 {};47struct _2 {};48 49// Replaces all occurrences of _1 with Arg1 and _2 with Arg2 in T.50template<typename T, typename Arg1, typename Arg2>51struct Replace {52  typedef T type;53};54 55// Replacement of the whole type.56template<typename Arg1, typename Arg2>57struct Replace<_1, Arg1, Arg2> {58  typedef Arg1 type;59};60 61template<typename Arg1, typename Arg2>62struct Replace<_2, Arg1, Arg2> {63  typedef Arg2 type;64};65 66// Replacement through cv-qualifiers67template<typename T, typename Arg1, typename Arg2>68struct Replace<const T, Arg1, Arg2> {69  typedef typename Replace<T, Arg1, Arg2>::type const type;70};71 72// Replacement of templates73template<template<typename> class TT, typename T1, typename Arg1, typename Arg2>74struct Replace<TT<T1>, Arg1, Arg2> {75  typedef TT<typename Replace<T1, Arg1, Arg2>::type> type;76};77 78template<template<typename, typename> class TT, typename T1, typename T2,79         typename Arg1, typename Arg2>80struct Replace<TT<T1, T2>, Arg1, Arg2> {81  typedef TT<typename Replace<T1, Arg1, Arg2>::type,82             typename Replace<T2, Arg1, Arg2>::type> type;83};84 85// Just for kicks...86template<template<typename, typename> class TT, typename T1,87         typename Arg1, typename Arg2>88struct Replace<TT<T1, _2>, Arg1, Arg2> {89  typedef TT<typename Replace<T1, Arg1, Arg2>::type, Arg2> type;90};91 92int array0[is_same<Replace<_1, int, float>::type, int>::value? 1 : -1];93int array1[is_same<Replace<const _1, int, float>::type, const int>::value? 1 : -1];94int array2[is_same<Replace<vector<_1>, int, float>::type, vector<int> >::value? 1 : -1];95int array3[is_same<Replace<vector<const _1>, int, float>::type, vector<const int> >::value? 1 : -1];96int array4[is_same<Replace<vector<int, _2>, double, float>::type, vector<int, float> >::value? 1 : -1];97 98// PR591199template <typename T, int N> void f(const T (&a)[N]);100int iarr[] = { 1 };101void test_PR5911() { f(iarr); }102 103// Must not examine base classes of incomplete type during template argument104// deduction.105namespace PR6257 {106  template <typename T> struct X {107    template <typename U> X(const X<U>& u);108  };109  struct A;110  void f(A& a);111  void f(const X<A>& a);112  void test(A& a) { (void)f(a); }113}114 115// PR7463116namespace PR7463 {117  const int f ();118  template <typename T_> void g (T_&); // expected-note{{T_ = int}}119  void h (void) { g(f()); } // expected-error{{no matching function for call}}120}121 122namespace test0 {123  template <class T> void make(const T *(*fn)()); // expected-note {{candidate template ignored: cannot deduce a type for 'T' that would make 'const T' equal 'char'}}124  char *char_maker();125  void test() {126    make(char_maker); // expected-error {{no matching function for call to 'make'}}127  }128}129 130namespace test1 {131  template<typename T> void foo(const T a[3][3]);132  void test() {133    int a[3][3];134    foo(a);135  }136}137 138// PR7708139namespace test2 {140  template<typename T> struct Const { typedef void const type; };141 142  template<typename T> void f(T, typename Const<T>::type*);143  template<typename T> void f(T, void const *);144 145  void test() {146    void *p = 0;147    f(0, p);148  }149}150 151namespace test3 {152  struct Foo {153    template <void F(char)> static inline void foo();154  };155 156  class Bar {157    template<typename T> static inline void wobble(T ch);158 159  public:160    static void madness() {161      Foo::foo<wobble<char> >();162    }163  };164}165 166namespace test4 {167 168template <class> struct a { using b = const float; };169template <class c> using d = typename a<c>::b;170 171template <class c> void e(d<c> *, c) {}172template void e(const float *, int);173 174} // namespace test4175 176namespace test5 {177 178template <bool, int = 0> class a {};179template <class b> void c(b, b);180template <bool b> void c(a<b>, a<b>);181void d() { c(a<true>(), a<true>()); }182 183} // namespace test5184 185namespace test6 {186template <class A1> using A = A1;187 188template <class F1, class... F2> void f(A<F1>, F1, F2...);189template <class F3> void f(A<F3>, F3);190 191void g() { f(A<int>{}, int{}); }192} // namespace test6193 194namespace test7 {195template <class T> void f(T&, T&);196template <class T, unsigned long S> void f(T (&)[S], T (&)[S]);197 198void g() {199  int i[3], j[3];200  f(i, j);201}202} // namespace test7203 204namespace test8 {205template <class T> void foo(T);206void test(int a) { // expected-note {{declared here}}207    char n[a]; // expected-warning {{variable length arrays in C++ are a Clang extension}} \208                  expected-note {{function parameter 'a' with unknown value cannot be used in a constant expression}}209    foo(n);210}211} // namespace test8212 213// Verify that we can deduce enum-typed arguments correctly.214namespace test14 {215  enum E { E0, E1 };216  template <E> struct A {};217  template <E e> void foo(const A<e> &a) {}218 219  void test() {220    A<E0> a;221    foo(a);222  }223}224 225namespace PR21536 {226  template<typename ...T> struct X;227  template<typename A, typename ...B> struct S {228    static_assert(sizeof...(B) == 1, "");229    void f() {230      using T = A;231      using T = int;232 233      using U = X<B...>;234      using U = X<int>;235    }236  };237  template<typename ...T> void f(S<T...>);238  void g() { f(S<int, int>()); }239}240 241namespace PR19372 {242  template <template<typename...> class C, typename ...Us> struct BindBack {243    template <typename ...Ts> using apply = C<Ts..., Us...>;244  };245  template <typename, typename...> struct Y;246  template <typename ...Ts> using Z = Y<Ts...>;247 248  using T = BindBack<Z, int>::apply<>;249  using T = Z<int>;250 251  using U = BindBack<Z, int, int>::apply<char>;252  using U = Z<char, int, int>;253 254  namespace BetterReduction {255    template<typename ...> struct S;256    template<typename ...A> using X = S<A...>; // expected-note {{parameter}}257    template<typename ...A> using Y = X<A..., A...>;258    template<typename ...A> using Z = X<A..., 1, 2, 3>; // expected-error {{must be a type}}259 260    using T = Y<int>;261    using T = S<int, int>;262  }263}264 265namespace PR18645 {266  template<typename F> F Quux(F &&f);267  auto Baz = Quux(Quux<float>);268}269 270namespace NonDeducedNestedNameSpecifier {271  template<typename T> struct A {272    template<typename U> struct B {273      B(int) {}274    };275  };276 277  template<typename T> int f(A<T>, typename A<T>::template B<T>);278  int k = f(A<int>(), 0);279}280 281namespace PR27601_RecursivelyInheritedBaseSpecializationsDeductionAmbiguity {282namespace ns1 {283 284template<class...> struct B { };285template<class H, class ... Ts> struct B<H, Ts...> : B<> { };286template<class ... Ts> struct D : B<Ts...> { };287 288template<class T, class ... Ts> void f(B<T, Ts...> &) { }289 290int main() {291  D<int, char> d;292  f<int>(d);293}294} //end ns1295 296namespace ns2 {297 298template <int i, typename... Es> struct tup_impl;299 300template <int i> struct tup_impl<i> {}; // empty tail301 302template <int i, typename Head, typename... Tail>303struct tup_impl<i, Head, Tail...> : tup_impl<i + 1, Tail...> {304  using value_type = Head;305  Head head;306};307 308template <typename... Es> struct tup : tup_impl<0, Es...> {};309 310template <typename Head, int i, typename... Tail>311Head &get_helper(tup_impl<i, Head, Tail...> &t) {312  return t.head;313}314 315template <typename Head, int i, typename... Tail>316Head const &get_helper(tup_impl<i, Head, Tail...> const &t) {317  return t.head;318}319 320int main() {321  tup<int, double, char> t;322  get_helper<double>(t);323  return 0;324}325} // end ns2326}327 328namespace multiple_deduction_different_type {329  template<typename T, T v> struct X {};330  template<template<typename T, T> class X, typename T, typename U, int N>331    void f(X<T, N>, X<U, N>) {} // expected-note 2{{values of conflicting types}}332  template<template<typename T, T> class X, typename T, typename U, const int *N>333    void g(X<T, N>, X<U, N>) {} // expected-note 0-2{{values of conflicting types}}334  int n;335  void h() {336    f(X<int, 1+1>(), X<unsigned int, 3-1>()); // expected-error {{no matching function}}337    f(X<unsigned int, 1+1>(), X<int, 3-1>()); // expected-error {{no matching function}}338#if __cplusplus > 201402L339    g(X<const int*, &n>(), X<int*, &n + 1 - 1>()); // expected-error {{no matching function}}340    g(X<int*, &n>(), X<const int*, &n + 1 - 1>()); // expected-error {{no matching function}}341#endif342  }343 344  template<template<typename T, T> class X, typename T, typename U, T N>345    void x(X<T, N>, int(*)[N], X<U, N>) {} // expected-note 1+{{candidate}}346  template<template<typename T, T> class X, typename T, typename U, T N>347    void x(int(*)[N], X<T, N>, X<U, N>) {} // expected-note 1+{{candidate}}348  int arr[3];349  void y() {350    x(X<int, 3>(), &arr, X<int, 3>());351    x(&arr, X<int, 3>(), X<int, 3>());352 353    x(X<int, 3>(), &arr, X<char, 3>()); // expected-error {{no matching function}}354    x(&arr, X<int, 3>(), X<char, 3>()); // expected-error {{no matching function}}355 356    x(X<char, 3>(), &arr, X<char, 3>());357    x(&arr, X<char, 3>(), X<char, 3>());358  }359}360 361namespace nullptr_deduction {362  using nullptr_t = decltype(nullptr);363 364  template<typename T, T v> struct X {};365  template<typename T, T v> void f(X<T, v>) {366    static_assert(!v, ""); // expected-warning 2{{implicit conversion of nullptr constant to 'bool'}}367  }368  void g() {369    f(X<int*, nullptr>()); // expected-note {{instantiation of}}370    f(X<nullptr_t, nullptr>()); // expected-note {{instantiation of}}371  }372 373  template<template<typename T, T> class X, typename T, int *P>374    void f0(X<T, P>) {} // expected-note {{deduced non-type template argument does not have the same type as the corresponding template parameter ('std::nullptr_t' vs 'int *')}}375  void h0() {376    f0(X<int*, nullptr>());377    f0(X<nullptr_t, nullptr>()); // expected-error {{no matching function}}378  }379 380  template<template<typename T, T> class X, typename T, typename U, int *P>381    void f1(X<T, P>, X<U, P>) {} // expected-note 2{{values of conflicting types}}382  void h() {383    f1(X<int*, nullptr>(), X<nullptr_t, nullptr>()); // expected-error {{no matching function}}384    f1(X<nullptr_t, nullptr>(), X<int*, nullptr>()); // expected-error {{no matching function}}385  }386 387  template<template<typename T, T> class X, typename T, typename U, nullptr_t P>388    void f2(X<T, P>, X<U, P>) {} // expected-note 2{{values of conflicting types}}389  void i() {390    f2(X<int*, nullptr>(), X<nullptr_t, nullptr>()); // expected-error {{no matching function}}391    f2(X<nullptr_t, nullptr>(), X<int*, nullptr>()); // expected-error {{no matching function}}392  }393}394 395namespace member_pointer {396  struct A { void f(int); };397  template<typename T, void (A::*F)(T)> struct B;398  template<typename T> struct C;399  template<typename T, void (A::*F)(T)> struct C<B<T, F>> {400    C() { A a; T t; (a.*F)(t); }401  };402  C<B<int, &A::f>> c;403}404 405namespace deduction_substitution_failure {406  template<typename T> struct Fail { typedef typename T::error error; }; // expected-error 2{{prior to '::'}}407 408  template<typename T, typename U> struct A {};409  template<typename T> struct A<T, typename Fail<T>::error> {}; // expected-note {{instantiation of}}410  A<int, int> ai; // expected-note {{during template argument deduction for class template partial specialization 'A<T, typename Fail<T>::error>' [with T = int]}} expected-note {{in instantiation of template class 'deduction_substitution_failure::A<int, int>'}}411 412  template<typename T, typename U> int B; // expected-warning 0-1 {{extension}}413  template<typename T> int B<T, typename Fail<T>::error> {}; // expected-note {{instantiation of}}414  int bi = B<char, char>; // expected-note {{during template argument deduction for variable template partial specialization 'B<T, typename Fail<T>::error>' [with T = char]}}415}416 417namespace deduce_pack_from_argument {418  template <typename... T>419  void separator(args_tag<T...>, T..., int, T...) {}420  template <typename... T>421  void separator_dependent(args_tag<T...>, type_identity_t<T>..., int, type_identity_t<T>...) {}422  template <typename... Y, typename... T>423  void separator_multiple_parameters(args_tag<Y...>, args_tag<T...>, type_identity_t<T>..., int mid, type_identity_t<T>...) {}424 425  void test_separator() {426    separator(args_tag<int, int>{}, 4, 8, 42, 16, 25);427    separator(args_tag<>{}, 42);428    separator_dependent(args_tag<int, int>{}, 4, 8, 42, 16, 25);429    separator_dependent(args_tag<>{}, 42);430    separator_multiple_parameters(args_tag<const int, const int>{}, args_tag<int, int>{}, 8, 9, 15, 16, 23);431  }432 433  template <typename... Y, typename... T> void no_separator(args_tag<T...>, T..., T...) {}434  template <typename... Y, typename... T>435  void no_separator_dependent(args_tag<Y...>, args_tag<T...>, type_identity_t<T>..., type_identity_t<T>...) {}436 437  void test_no_separator() {438    no_separator(args_tag<int, int>{}, 1, 2, 3, 4);439    no_separator(args_tag<>{});440    no_separator_dependent(args_tag<const int, const int>{}, args_tag<int, int>{}, 8, 9, 15, 16);441    no_separator_dependent(args_tag<>{}, args_tag<>{});442  }443}444 445namespace deduction_after_explicit_pack {446  template<typename ...T, typename U> int *f(T ...t, int &r, U *u) {447    return u;448  }449  template<typename U, typename ...T> int *g(T ...t, int &r, U *u) {450    return u;451  }452  void h(float a, double b, int c) {453    f<float&, double&>(a, b, c, &c); // ok454    g<int, float&, double&>(a, b, c, &c); // ok455  }456 457  template<class... ExtraArgs>458  int test(ExtraArgs..., unsigned vla_size, const char *input);459  int n = test(0, "");460 461  template <typename... T> void i(T..., int, T..., ...); // expected-note 5{{deduced packs of different lengths}}462  void j() {463    i(0);464    i(0, 1); // expected-error {{no match}}465    i(0, 1, 2); // expected-error {{no match}}466    i<>(0);467    i<>(0, 1); // expected-error {{no match}}468    i<>(0, 1, 2); // expected-error {{no match}}469    i<int, int>(0, 1, 2, 3, 4);470    i<int, int>(0, 1, 2, 3, 4, 5); // expected-error {{no match}}471  }472 473  // GCC alarmingly accepts this by deducing T={int} by matching the second474  // parameter against the first argument, then passing the first argument475  // through the first parameter.476  template<typename... T> struct X { X(int); operator int(); };477  template<typename... T> void p(T..., X<T...>, ...); // expected-note {{deduced packs of different lengths for parameter 'T' (<> vs. <int>)}}478  void q() { p(X<int>(0), 0); } // expected-error {{no match}}479 480  struct A {481    template <typename T> void f(T, void *, int = 0); // expected-note 2{{no known conversion from 'double' to 'void *' for 2nd argument}}482    void f(); // expected-note 2{{requires 0}}483 484    template <typename T> static void g(T, void *, int = 0); // expected-note 2{{no known conversion from 'double' to 'void *' for 2nd argument}}485    void g(); // expected-note 2{{requires 0}}486 487    void h() {488      f(1.0, 2.0); // expected-error {{no match}}489      g(1.0, 2.0); // expected-error {{no match}}490    }491  };492  void f(A a) {493    a.f(1.0, 2.0); // expected-error {{no match}}494    a.g(1.0, 2.0); // expected-error {{no match}}495  }496}497 498namespace overload_vs_pack {499  void f(int);500  void f(float);501  void g(double);502 503  template<typename ...T> struct X {};504  template<typename ...T> void x(T...);505 506  template<typename ...T> struct Y { typedef int type(typename T::error...); };507  template<> struct Y<int, float, double> { typedef int type; };508 509  template<typename ...T> typename Y<T...>::type g1(X<T...>, void (*...fns)(T)); // expected-note {{deduced conflicting types for parameter 'T' (<int, float> vs. <(no value), double>)}}510  template<typename ...T> typename Y<T...>::type g2(void(*)(T...), void (*...fns)(T)); // expected-note {{deduced conflicting types for parameter 'T' (<int, float> vs. <(no value), double>)}}511 512  template<typename T> int &h1(decltype(g1(X<int, float, T>(), f, f, g)) *p);513  template<typename T> float &h1(...);514 515  template<typename T> int &h2(decltype(g2(x<int, float, T>, f, f, g)) *p);516  template<typename T> float &h2(...);517 518  int n1 = g1(X<int, float>(), f, g); // expected-error {{no matching function}}519  int n2 = g2(x<int, float>, f, g); // expected-error {{no matching function}}520 521  int &a1 = h1<double>(0); // ok, skip deduction for 'f's, deduce matching value from 'g'522  int &a2 = h2<double>(0);523 524  float &b1 = h1<float>(0); // deduce mismatching value from 'g', so we do not trigger instantiation of Y525  float &b2 = h2<float>(0);526 527  template<typename ...T> int partial_deduction(void (*...f)(T)); // expected-note {{deduced incomplete pack <(no value), double> for template parameter 'T'}}528  int pd1 = partial_deduction(f, g); // expected-error {{no matching function}}529 530  template<typename ...T> int partial_deduction_2(void (*...f)(T), ...); // expected-note {{deduced incomplete pack <(no value), double> for template parameter 'T'}}531  int pd2 = partial_deduction_2(f, g); // expected-error {{no matching function}}532 533  namespace cwg_example {534    void f(char, char);535    void f(int, int);536    void x(int, char);537 538    template<typename T, typename ...U> void j(void(*)(U...), void (*...fns)(T, U));539    void test() { j(x, f, x); }540  }541}542 543namespace b29946541 {544  template<typename> class A {};545  template<typename T, typename U, template<typename, typename> class C>546  void f(C<T, U>); // expected-note {{failed template argument deduction}}547  void g(A<int> a) { f(a); } // expected-error {{no match}}548}549 550namespace deduction_from_empty_list {551  template<int M, int N = 5> void f(int (&&)[N], int (&&)[N]) { // expected-note {{1 vs. 2}}552    static_assert(M == N, "");553  }554 555  void test() {556    f<5>({}, {});557    f<1>({}, {0});558    f<1>({0}, {});559    f<1>({0}, {0});560    f<1>({0}, {0, 1}); // expected-error {{no matching}}561  }562}563 564namespace check_extended_pack {565  template<typename T> struct X { typedef int type; };566  template<typename ...T> void f(typename X<T>::type...);567  template<typename T> void f(T, int, int);568  void g() {569    f<int>(0, 0, 0);570  }571 572  template<int, int*> struct Y {};573  template<int ...N> void g(Y<N...>); // expected-note {{deduced non-type template argument does not have the same type as the corresponding template parameter ('int *' vs 'int')}}574  int n;575  void h() { g<0>(Y<0, &n>()); } // expected-error {{no matching function}}576}577 578namespace dependent_template_template_param_non_type_param_type {579  template<int N> struct A {580    template<typename V = int, V M = 12, V (*Y)[M], template<V (*v)[M]> class W>581    A(W<Y>);582  };583 584  int n[12];585  template<int (*)[12]> struct Q {};586  Q<&n> qn;587  A<0> a(qn);588}589 590namespace dependent_list_deduction {591  template<typename T, T V> void a(const int (&)[V]) {592    static_assert(is_same<T, decltype(sizeof(0))>::value, "");593    static_assert(V == 3, "");594  }595  template<typename T, T V> void b(const T (&)[V]) {596    static_assert(is_same<T, int>::value, "");597    static_assert(V == 3, "");598  }599  template<typename T, T V> void c(const T (&)[V]) {600    static_assert(is_same<T, decltype(sizeof(0))>::value, "");601    static_assert(V == 3, "");602  }603  void d() {604    a({1, 2, 3});605#if __cplusplus <= 201402L606    // expected-error@-2 {{no match}} expected-note@-15 {{couldn't infer template argument 'T'}}607#endif608    b({1, 2, 3});609    c({{}, {}, {}});610#if __cplusplus <= 201402L611    // expected-error@-2 {{no match}} expected-note@-12 {{couldn't infer template argument 'T'}}612#endif613  }614 615  template<typename ...T> struct X;616  template<int ...T> struct Y;617  template<typename ...T, T ...V> void f(const T (&...p)[V]) {618    static_assert(is_same<X<T...>, X<int, char, char>>::value, "");619    static_assert(is_same<Y<V...>, Y<3, 2, 4>>::value, "");620  }621  template<typename ...T, T ...V> void g(const T (&...p)[V]) {622    static_assert(is_same<X<T...>, X<int, decltype(sizeof(0))>>::value, "");623    static_assert(is_same<Y<V...>, Y<2, 3>>::value, "");624  }625  void h() {626    f({1, 2, 3}, {'a', 'b'}, "foo");627    g({1, 2}, {{}, {}, {}});628#if __cplusplus <= 201402629    // expected-error@-2 {{no match}}630    // expected-note@-9 {{deduced incomplete pack}}631    // We deduce V$1 = (size_t)3, which in C++1z also deduces T$1 = size_t.632#endif633  }634}635 636namespace designators {637  template<typename T, int N> constexpr int f(T (&&)[N]) { return N; } // expected-note 2{{couldn't infer template argument 'T'}}638  static_assert(f({1, 2, [20] = 3}) == 3, ""); // expected-error {{no matching function}} expected-warning 2{{C99}} expected-note {{}}639 640  static_assert(f({.a = 1, .b = 2}) == 3, ""); // expected-error {{no matching function}}641}642 643namespace nested_packs {644  template<typename ...T, typename ...U> void f(T (*...f)(U...)); // expected-note {{deduced packs of different lengths for parameter 'U' (<> vs. <int>)}}645  void g() { f(g); f(g, g); f(g, g, g); }646  void h(int) { f(h); f(h, h); f(h, h, h); }647  void i() { f(g, h); } // expected-error {{no matching function}}648 649#if __cplusplus >= 201703L650  template<auto ...A> struct Q {};651  template<typename ...T, T ...A, T ...B> void q(Q<A...>, Q<B...>); // #q652  void qt(Q<> q0, Q<1, 2> qii, Q<1, 2, 3> qiii) {653    q(q0, q0);654    q(qii, qii);655    q(qii, qiii); // expected-error {{no match}} expected-note@#q {{deduced packs of different lengths for parameter 'T' (<int, int> vs. <int, int, int>)}}656    q(q0, qiii); // expected-error {{no match}} expected-note@#q {{deduced packs of different lengths for parameter 'T' (<> vs. <int, int, int>)}}657  }658#endif659}660 661namespace PR44890 {662  template<typename ...Ts>663    struct tuple {};664 665  template<int I, typename ...Ts>666    int get0(const tuple<Ts...> &t) { return 0; }667 668  template<typename ...Ts> struct tuple_wrapper : tuple<Ts...> {669    template<int I> int get() { return get0<0, Ts...>(*this); }670  };671 672  int f() {673    tuple_wrapper<int> w;674    return w.get<0>();675  }676}677 678namespace merge_size_only_deductions {679#if __cplusplus >= 201703L680  // Based on a testcase by Hubert Tong.681  template<typename ...> struct X {};682  template<auto ...> struct Y {};683  template<typename T> struct id { using Type = T; };684 685  template<typename ...T, typename T::Type ...V>686    int f(X<char [V] ...>, Y<V ...>, X<T ...>);687 688  using size_t = __SIZE_TYPE__;689  int a = f(X<char [1], char [2]>(), Y<(size_t)1, (size_t)2>(), X<id<size_t>, id<size_t>>());690  int b = f(X<char [1], char [2]>(), Y<1, 2>(), X<id<int>, id<int>>());691#endif692}693 694namespace PR49724 {695  struct A;696  template<int A::*> class X {};697  template<int A::*P> void f(X<P>);698  void g(X<nullptr> x) { f(x); }699 700  template<void (A::*)()> class Y {};701  template<void (A::*P)()> void f(Y<P>);702  void g(Y<nullptr> y) { f(y); }703}704 705namespace sugared_deduction {706using Int = int;707 708template <class T, int C> void f1(T(&)[C], T(&)[C+1]);709// expected-note@-1 {{candidate template ignored: deduced type 'int[3]' of 2nd parameter does not match adjusted type 'Int[2]' (aka 'int[2]') of argument [with T = Int, C = 2]}}710 711void t1() {712  Int a[2], b[2];713  f1(a, b); // expected-error {{no matching function for call to 'f1'}}714}715 716#if defined(__cpp_concepts)717template <class T> void f2() requires false {}718// expected-note@-1 {{candidate template ignored: constraints not satisfied [with T = Int]}}719// expected-note@-2 {{because 'false' evaluated to false}}720 721void t2() {722  f2<Int>(); // expected-error {{no matching function for call to 'f2'}}723}724#endif725} // namespace sugared_deduction726