// RUN: %clang_cc1 -std=c++1z -verify %s // Test that we cope with failure to expand a pack. template struct Unexpanded : T... { using T::f; // expected-error {{unexpanded}} using typename T::type; // expected-error {{unexpanded}} template void g(U ...u) { f(u...); } // expected-error {{explicit qualification required to use member 'f' from dependent base class}} void h() { Unexpanded *p; // expected-error {{undeclared identifier 'type'}} } }; void test_Unexpanded() { struct A { void f(); }; struct B { void f(int); }; // expected-note {{here}} Unexpanded().g(0); // expected-note {{instantiation of}} } // Test using non-type members from pack of base classes. template struct A : T... { using T::T ...; // expected-note 2{{inherited here}} using T::operator() ...; using T::operator T* ...; using T::h ...; void f(int n) { h(n); } // expected-error {{ambiguous}} void f(int n, int m) { h(n, m); } // expected-error {{member using declaration 'h' instantiates to an empty pack}} void g(int n) { (*this)(n); } // expected-error {{ambiguous}} void g(int n, int m) { (*this)(n, m); } // expected-error {{does not provide a call operator}} }; namespace test_A { struct X { X(); X(int); // expected-note {{candidate}} void operator()(int); // expected-note 2{{candidate}} operator X *(); void h(int); // expected-note {{candidate}} }; struct Y { Y(); Y(int, int); void operator()(int, int); operator Y *(); void h(int, int); }; struct Z { Z(); Z(int); // expected-note {{candidate}} void operator()(int); // expected-note 2{{candidate}} operator Z *(); void h(int); // expected-note {{candidate}} }; void f() { A<> a; a.f(0, 0); // expected-note {{instantiation of}} a.g(0, 0); // expected-note {{instantiation of}} A axy(0); A(0, 0); axy.f(0); axy.f(0, 0); axy.g(0); axy.g(0, 0); axy(0); axy(0, 0); A(0); // expected-error {{ambiguous}} A axyz(0, 0); axyz.f(0); // expected-note {{instantiation of}} axyz.f(0, 0); axyz.g(0); // expected-note {{instantiation of}} axyz.g(0, 0); axyz(0); // expected-error {{ambiguous}} axyz(0, 0); X *x; x = a; // expected-error {{incompatible}} x = axy; x = axyz; x = a.operator X*(); // expected-error {{no member}} x = axy.operator X*(); x = axyz.operator X*(); Z *z; z = axyz; z = axyz.operator Z*(); } } // Test using pack of non-type members from single base class. template struct B : X, Y { using X::operator T* ...; }; namespace test_B { struct X { operator int*(); operator float*(); operator char*(); }; // expected-note {{candidate}} struct Y { operator int*(); operator float*(); operator char*(); }; // expected-note {{candidate}} B bif; int *pi = bif; float *pf = bif; char *pc = bif; // expected-error {{ambiguous}} } // Test using type member from pack of base classes. template struct C : T... { using typename T::type ...; // expected-error {{target of using declaration conflicts}} void f() { type value; } // expected-error {{member using declaration 'type' instantiates to an empty pack}} }; namespace test_C { struct X { typedef int type; }; struct Y { typedef int type; }; // expected-note {{conflicting}} struct Z { typedef float type; }; // expected-note {{target}} void f() { C<> c; c.f(); // expected-note {{instantiation of}} C cxy; cxy.f(); C cxyz; // expected-note {{instantiation of}} cxyz.f(); } } // Test using pack of non-types at block scope. template int fn1() { using T::e ...; // expected-error 2{{class member}} expected-note 2{{instead}} // expected-error@-1 2{{produces multiple values}} return e; // expected-error {{using declaration 'e' instantiates to an empty pack}} } namespace test_fn1 { struct X { static int e; }; struct Y { typedef int e; }; inline namespace P { enum E { e }; } inline namespace Q { enum F { e }; } void f() { fn1<>(); // expected-note {{instantiation of}} fn1(); // expected-note {{instantiation of}} fn1(); // expected-note {{instantiation of}} fn1(); fn1(); // expected-note {{instantiation of}} fn1(); // expected-note {{instantiation of}} } } // Test using pack of types at block scope. template void fn2() { // This cannot ever be valid: in order for T::type to be a type, T must be a // class, and a class member cannot be named by a block-scope using declaration. using typename T::type ...; // expected-error {{class member}} type x; // expected-error {{unknown type name 'type'}} } // Test partial substitution into class-scope pack. template auto lambda1() { return [](auto x) { struct A : T::template X... { // expected-note 1+{{instantiation of}} using T::template X::f ...; using typename T::template X::type ...; void g(int n) { f(n); } // expected-error {{empty pack}} expected-error {{expected 2, have 1}} expected-error {{ambiguous}} void h() { type value; } // expected-error {{empty pack}} }; return A(); }; } namespace test_lambda1 { struct A { template struct X { void f(int); // expected-note {{candidate}} using type = int; }; }; struct B { template struct X { void f(int, int); // expected-note {{declared here}} using type = int; }; }; struct C { template struct X { void f(int); // expected-note {{candidate}} void f(int, int); using type = int; }; }; void f() { lambda1<>() // expected-note 2{{instantiation of}} (0) // FIXME: This is poor error recovery .g(0); // expected-error {{no member named 'g'}} lambda1() (0) .g(0); lambda1() (0) // expected-note {{instantiation of}} .g(0); lambda1() (0) // expected-note {{instantiation of}} .g(0); } } namespace p0195r2_example { template struct Overloader : Ts... { using Ts::operator() ...; }; template constexpr auto make_overloader(Ts &&...ts) { return Overloader{static_cast(ts)...}; } void test() { auto o = make_overloader( [&](int &r) -> int & { return r; }, // expected-note {{candidate function}} [&](float &r) -> float & { return r; } // expected-note {{candidate function}} ); int a; float f; double d; int &ra = o(a); float &rf = o(f); double &rd = o(d); // expected-error {{no matching function}} } }