// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++1z // Template argument deduction with template template parameters. template class A> struct X0 { static const unsigned value = 0; }; template class A> struct X0 { static const unsigned value = 1; }; template struct X0i; template struct X0l; int array_x0a[X0::value == 0? 1 : -1]; int array_x0b[X0::value == 1? 1 : -1]; template struct is_same { static const bool value = false; }; template struct is_same { static const bool value = true; }; template struct allocator { }; template > struct vector {}; // Fun with meta-lambdas! struct _1 {}; struct _2 {}; // Replaces all occurrences of _1 with Arg1 and _2 with Arg2 in T. template struct Replace { typedef T type; }; // Replacement of the whole type. template struct Replace<_1, Arg1, Arg2> { typedef Arg1 type; }; template struct Replace<_2, Arg1, Arg2> { typedef Arg2 type; }; // Replacement through cv-qualifiers template struct Replace { typedef typename Replace::type const type; }; // Replacement of templates template class TT, typename T1, typename Arg1, typename Arg2> struct Replace, Arg1, Arg2> { typedef TT::type> type; }; template class TT, typename T1, typename T2, typename Arg1, typename Arg2> struct Replace, Arg1, Arg2> { typedef TT::type, typename Replace::type> type; }; // Just for kicks... template class TT, typename T1, typename Arg1, typename Arg2> struct Replace, Arg1, Arg2> { typedef TT::type, Arg2> type; }; int array0[is_same::type, int>::value? 1 : -1]; int array1[is_same::type, const int>::value? 1 : -1]; int array2[is_same, int, float>::type, vector >::value? 1 : -1]; int array3[is_same, int, float>::type, vector >::value? 1 : -1]; int array4[is_same, double, float>::type, vector >::value? 1 : -1]; // PR5911 template void f(const T (&a)[N]); int iarr[] = { 1 }; void test_PR5911() { f(iarr); } // Must not examine base classes of incomplete type during template argument // deduction. namespace PR6257 { template struct X { template X(const X& u); }; struct A; void f(A& a); void f(const X& a); void test(A& a) { (void)f(a); } } // PR7463 namespace PR7463 { const int f (); template void g (T_&); // expected-note{{T_ = int}} void h (void) { g(f()); } // expected-error{{no matching function for call}} } namespace test0 { template void make(const T *(*fn)()); // expected-note {{candidate template ignored: cannot deduce a type for 'T' that would make 'const T' equal 'char'}} char *char_maker(); void test() { make(char_maker); // expected-error {{no matching function for call to 'make'}} } } namespace test1 { template void foo(const T a[3][3]); void test() { int a[3][3]; foo(a); } } // PR7708 namespace test2 { template struct Const { typedef void const type; }; template void f(T, typename Const::type*); template void f(T, void const *); void test() { void *p = 0; f(0, p); } } // rdar://problem/8537391 namespace test3 { struct Foo { template static inline void foo(); }; class Bar { template static inline void wobble(T ch); public: static void madness() { Foo::foo >(); } }; } // Verify that we can deduce enum-typed arguments correctly. namespace test14 { enum E { E0, E1 }; template struct A {}; template void foo(const A &a) {} void test() { A a; foo(a); } } namespace PR21536 { template struct X; template struct S { static_assert(sizeof...(B) == 1, ""); void f() { using T = A; using T = int; using U = X; using U = X; } }; template void f(S); void g() { f(S()); } } namespace PR19372 { template class C, typename ...Us> struct BindBack { template using apply = C; }; template struct Y; template using Z = Y; using T = BindBack::apply<>; using T = Z; using U = BindBack::apply; using U = Z; namespace BetterReduction { template struct S; template using X = S; // expected-note {{parameter}} template using Y = X; template using Z = X; // expected-error {{must be a type}} using T = Y; using T = S; } } namespace PR18645 { template F Quux(F &&f); auto Baz = Quux(Quux); } namespace NonDeducedNestedNameSpecifier { template struct A { template struct B { B(int) {} }; }; template int f(A, typename A::template B); int k = f(A(), 0); } namespace PR27601_RecursivelyInheritedBaseSpecializationsDeductionAmbiguity { namespace ns1 { template struct B { }; template struct B : B<> { }; template struct D : B { }; template void f(B &) { } int main() { D d; f(d); } } //end ns1 namespace ns2 { template struct tup_impl; template struct tup_impl {}; // empty tail template struct tup_impl : tup_impl { using value_type = Head; Head head; }; template struct tup : tup_impl<0, Es...> {}; template Head &get_helper(tup_impl &t) { return t.head; } template Head const &get_helper(tup_impl const &t) { return t.head; } int main() { tup t; get_helper(t); return 0; } } // end ns2 } namespace multiple_deduction_different_type { template struct X {}; template class X, typename T, typename U, int N> void f(X, X) {} // expected-note 2{{values of conflicting types}} template class X, typename T, typename U, const int *N> void g(X, X) {} // expected-note 0-2{{values of conflicting types}} int n; void h() { f(X(), X()); // expected-error {{no matching function}} f(X(), X()); // expected-error {{no matching function}} #if __cplusplus > 201402L g(X(), X()); // expected-error {{no matching function}} g(X(), X()); // expected-error {{no matching function}} #endif } template class X, typename T, typename U, T N> void x(X, int(*)[N], X) {} // expected-note 1+{{candidate}} template class X, typename T, typename U, T N> void x(int(*)[N], X, X) {} // expected-note 1+{{candidate}} int arr[3]; void y() { x(X(), &arr, X()); x(&arr, X(), X()); x(X(), &arr, X()); // expected-error {{no matching function}} x(&arr, X(), X()); // expected-error {{no matching function}} x(X(), &arr, X()); x(&arr, X(), X()); } } namespace nullptr_deduction { using nullptr_t = decltype(nullptr); template struct X {}; template void f(X) { static_assert(!v, ""); // expected-warning 2{{implicit conversion of nullptr constant to 'bool'}} } void g() { f(X()); // expected-note {{instantiation of}} f(X()); // expected-note {{instantiation of}} } template class X, typename T, int *P> void f0(X) {} // expected-note {{deduced non-type template argument does not have the same type as the corresponding template parameter ('nullptr_t' vs 'int *')}} void h0() { f0(X()); f0(X()); // expected-error {{no matching function}} } template class X, typename T, typename U, int *P> void f1(X, X) {} // expected-note 2{{values of conflicting types}} void h() { f1(X(), X()); // expected-error {{no matching function}} f1(X(), X()); // expected-error {{no matching function}} } template class X, typename T, typename U, nullptr_t P> void f2(X, X) {} // expected-note 2{{values of conflicting types}} void i() { f2(X(), X()); // expected-error {{no matching function}} f2(X(), X()); // expected-error {{no matching function}} } } namespace member_pointer { struct A { void f(int); }; template struct B; template struct C; template struct C> { C() { A a; T t; (a.*F)(t); } }; C> c; } namespace deduction_substitution_failure { template struct Fail { typedef typename T::error error; }; // expected-error 2{{prior to '::'}} template struct A {}; template struct A::error> {}; // expected-note {{instantiation of}} A ai; // expected-note {{during template argument deduction for class template partial specialization 'A::error>' [with T = int]}} expected-note {{in instantiation of template class 'deduction_substitution_failure::A'}} template int B; // expected-warning 0-1 {{extension}} template int B::error> {}; // expected-note {{instantiation of}} int bi = B; // expected-note {{during template argument deduction for variable template partial specialization 'B::error>' [with T = char]}} } namespace deduction_after_explicit_pack { template int *f(T ...t, int &r, U *u) { return u; } template int *g(T ...t, int &r, U *u) { return u; } void h(float a, double b, int c) { f(a, b, c, &c); // ok g(a, b, c, &c); // ok } template int test(ExtraArgs..., unsigned vla_size, const char *input); int n = test(0, ""); template void i(T..., int, T..., ...); // expected-note 5{{deduced packs of different lengths}} void j() { i(0); i(0, 1); // expected-error {{no match}} i(0, 1, 2); // expected-error {{no match}} i<>(0); i<>(0, 1); // expected-error {{no match}} i<>(0, 1, 2); // expected-error {{no match}} i(0, 1, 2, 3, 4); i(0, 1, 2, 3, 4, 5); // expected-error {{no match}} } // GCC alarmingly accepts this by deducing T={int} by matching the second // parameter against the first argument, then passing the first argument // through the first parameter. template struct X { X(int); operator int(); }; template void p(T..., X, ...); // expected-note {{deduced packs of different lengths for parameter 'T' (<> vs. )}} void q() { p(X(0), 0); } // expected-error {{no match}} struct A { template void f(T, void *, int = 0); // expected-note 2{{no known conversion from 'double' to 'void *' for 2nd argument}} void f(); // expected-note 2{{requires 0}} template static void g(T, void *, int = 0); // expected-note 2{{no known conversion from 'double' to 'void *' for 2nd argument}} void g(); // expected-note 2{{requires 0}} void h() { f(1.0, 2.0); // expected-error {{no match}} g(1.0, 2.0); // expected-error {{no match}} } }; void f(A a) { a.f(1.0, 2.0); // expected-error {{no match}} a.g(1.0, 2.0); // expected-error {{no match}} } } namespace overload_vs_pack { void f(int); void f(float); void g(double); template struct X {}; template void x(T...); template struct Y { typedef int type(typename T::error...); }; template<> struct Y { typedef int type; }; template typename Y::type g1(X, void (*...fns)(T)); // expected-note {{deduced conflicting types for parameter 'T' ( vs. <(no value), double>)}} template typename Y::type g2(void(*)(T...), void (*...fns)(T)); // expected-note {{deduced conflicting types for parameter 'T' ( vs. <(no value), double>)}} template int &h1(decltype(g1(X(), f, f, g)) *p); template float &h1(...); template int &h2(decltype(g2(x, f, f, g)) *p); template float &h2(...); int n1 = g1(X(), f, g); // expected-error {{no matching function}} int n2 = g2(x, f, g); // expected-error {{no matching function}} int &a1 = h1(0); // ok, skip deduction for 'f's, deduce matching value from 'g' int &a2 = h2(0); float &b1 = h1(0); // deduce mismatching value from 'g', so we do not trigger instantiation of Y float &b2 = h2(0); template int partial_deduction(void (*...f)(T)); // expected-note {{deduced incomplete pack <(no value), double> for template parameter 'T'}} int pd1 = partial_deduction(f, g); // expected-error {{no matching function}} template int partial_deduction_2(void (*...f)(T), ...); // expected-note {{deduced incomplete pack <(no value), double> for template parameter 'T'}} int pd2 = partial_deduction_2(f, g); // expected-error {{no matching function}} namespace cwg_example { void f(char, char); void f(int, int); void x(int, char); template void j(void(*)(U...), void (*...fns)(T, U)); void test() { j(x, f, x); } } } namespace b29946541 { template class A {}; template class C> void f(C); // expected-note {{failed template argument deduction}} void g(A a) { f(a); } // expected-error {{no match}} } namespace deduction_from_empty_list { template void f(int (&&)[N], int (&&)[N]) { // expected-note {{1 vs. 2}} static_assert(M == N, ""); } void test() { f<5>({}, {}); f<1>({}, {0}); f<1>({0}, {}); f<1>({0}, {0}); f<1>({0}, {0, 1}); // expected-error {{no matching}} } } namespace check_extended_pack { template struct X { typedef int type; }; template void f(typename X::type...); template void f(T, int, int); void g() { f(0, 0, 0); } template struct Y {}; template void g(Y); // expected-note {{deduced non-type template argument does not have the same type as the corresponding template parameter ('int *' vs 'int')}} int n; void h() { g<0>(Y<0, &n>()); } // expected-error {{no matching function}} } namespace dependent_template_template_param_non_type_param_type { template struct A { template class W> A(W); }; int n[12]; template struct Q {}; Q<&n> qn; A<0> a(qn); } namespace dependent_list_deduction { template void a(const int (&)[V]) { static_assert(is_same::value, ""); static_assert(V == 3, ""); } template void b(const T (&)[V]) { static_assert(is_same::value, ""); static_assert(V == 3, ""); } template void c(const T (&)[V]) { static_assert(is_same::value, ""); static_assert(V == 3, ""); } void d() { a({1, 2, 3}); #if __cplusplus <= 201402L // expected-error@-2 {{no match}} expected-note@-15 {{couldn't infer template argument 'T'}} #endif b({1, 2, 3}); c({{}, {}, {}}); #if __cplusplus <= 201402L // expected-error@-2 {{no match}} expected-note@-12 {{couldn't infer template argument 'T'}} #endif } template struct X; template struct Y; template void f(const T (&...p)[V]) { static_assert(is_same, X>::value, ""); static_assert(is_same, Y<3, 2, 4>>::value, ""); } template void g(const T (&...p)[V]) { static_assert(is_same, X>::value, ""); static_assert(is_same, Y<2, 3>>::value, ""); } void h() { f({1, 2, 3}, {'a', 'b'}, "foo"); g({1, 2}, {{}, {}, {}}); #if __cplusplus <= 201402 // expected-error@-2 {{no match}} // expected-note@-9 {{deduced incomplete pack}} // We deduce V$1 = (size_t)3, which in C++1z also deduces T$1 = size_t. #endif } } namespace designators { template constexpr int f(T (&&)[N]) { return N; } // expected-note 2{{couldn't infer template argument 'T'}} static_assert(f({1, 2, [20] = 3}) == 3, ""); // expected-error {{no matching function}} expected-warning 2{{C99}} expected-note {{}} static_assert(f({.a = 1, .b = 2}) == 3, ""); // expected-error {{no matching function}} } namespace nested_packs { template void f(T (*...f)(U...)); // expected-note {{deduced packs of different lengths for parameter 'U' (<> vs. )}} void g() { f(g); f(g, g); f(g, g, g); } void h(int) { f(h); f(h, h); f(h, h, h); } void i() { f(g, h); } // expected-error {{no matching function}} #if __cplusplus >= 201703L template struct Q {}; template void q(Q, Q); // #q void qt(Q<> q0, Q<1, 2> qii, Q<1, 2, 3> qiii) { q(q0, q0); q(qii, qii); q(qii, qiii); // expected-error {{no match}} expected-note@#q {{deduced packs of different lengths for parameter 'T' ( vs. )}} q(q0, qiii); // expected-error {{no match}} expected-note@#q {{deduced packs of different lengths for parameter 'T' (<> vs. )}} } #endif } namespace PR44890 { template struct tuple {}; template int get0(const tuple &t) { return 0; } template struct tuple_wrapper : tuple { template int get() { return get0<0, Ts...>(*this); } }; int f() { tuple_wrapper w; return w.get<0>(); } } namespace merge_size_only_deductions { #if __cplusplus >= 201703L // Based on a testcase by Hubert Tong. template struct X {}; template struct Y {}; template struct id { using Type = T; }; template int f(X, Y, X); using size_t = __SIZE_TYPE__; int a = f(X(), Y<(size_t)1, (size_t)2>(), X, id>()); int b = f(X(), Y<1, 2>(), X, id>()); #endif }