|  | // RUN: %clang_cc1 -std=c++1z -verify %s | 
|  |  | 
|  | // Test that we cope with failure to expand a pack. | 
|  | template<typename ...T> struct Unexpanded : T... { | 
|  | using T::f; // expected-error {{unexpanded}} | 
|  | using typename T::type; // expected-error {{unexpanded}} | 
|  | template<typename ...U> void g(U ...u) { f(u...); } // expected-error {{undeclared identifier 'f'}} | 
|  | void h() { | 
|  | Unexpanded<type...> *p; // expected-error {{undeclared identifier 'type'}} | 
|  | } | 
|  | }; | 
|  | void test_Unexpanded() { | 
|  | struct A { void f(); }; // expected-note {{must qualify}} | 
|  | struct B { void f(int); }; // expected-note {{must qualify}} | 
|  | Unexpanded<A, B>().g(0); // expected-note {{instantiation of}} | 
|  | } | 
|  |  | 
|  | // Test using non-type members from pack of base classes. | 
|  | template<typename ...T> struct A : T... { // expected-note 2{{candidate}} | 
|  | 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); // expected-note {{not viable}} | 
|  | }; | 
|  | 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<X, Y> axy(0); | 
|  | A<X, Y>(0, 0); | 
|  | axy.f(0); | 
|  | axy.f(0, 0); | 
|  | axy.g(0); | 
|  | axy.g(0, 0); | 
|  | axy(0); | 
|  | axy(0, 0); | 
|  |  | 
|  | A<X, Y, Z>(0); // expected-error {{ambiguous}} | 
|  | A<X, Y, Z> 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<typename X, typename Y, typename ...T> 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<X, Y, int, float> bif; | 
|  | int *pi = bif; | 
|  | float *pf = bif; | 
|  | char *pc = bif; // expected-error {{ambiguous}} | 
|  | } | 
|  |  | 
|  | // Test using type member from pack of base classes. | 
|  | template<typename ...T> 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<X, Y> cxy; | 
|  | cxy.f(); | 
|  |  | 
|  | C<X, Y, Z> cxyz; // expected-note {{instantiation of}} | 
|  | cxyz.f(); | 
|  | } | 
|  | } | 
|  |  | 
|  | // Test using pack of non-types at block scope. | 
|  | template<typename ...T> 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<X>(); // expected-note {{instantiation of}} | 
|  | fn1<Y>(); // expected-note {{instantiation of}} | 
|  | fn1<E>(); | 
|  | fn1<E, F>(); // expected-note {{instantiation of}} | 
|  | fn1<E, X>(); // expected-note {{instantiation of}} | 
|  | } | 
|  | } | 
|  |  | 
|  | // Test using pack of types at block scope. | 
|  | template<typename ...T> 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<typename ...T> auto lambda1() { | 
|  | return [](auto x) { | 
|  | struct A : T::template X<decltype(x)>... { // expected-note 1+{{instantiation of}} | 
|  | using T::template X<decltype(x)>::f ...; | 
|  | using typename T::template X<decltype(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<typename> struct X { | 
|  | void f(int); // expected-note {{candidate}} | 
|  | using type = int; | 
|  | }; | 
|  | }; | 
|  | struct B { | 
|  | template<typename> struct X { | 
|  | void f(int, int); // expected-note {{declared here}} expected-note {{not viable}} | 
|  | using type = int; | 
|  | }; | 
|  | }; | 
|  | struct C { | 
|  | template<typename> struct X { | 
|  | void f(int); // expected-note {{candidate}} | 
|  | void f(int, int); // expected-note {{not viable}} | 
|  | 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<A>() | 
|  | (0) | 
|  | .g(0); | 
|  | lambda1<B>() | 
|  | (0) // expected-note {{instantiation of}} | 
|  | .g(0); | 
|  | lambda1<A, B, C>() | 
|  | (0) // expected-note {{instantiation of}} | 
|  | .g(0); | 
|  | } | 
|  | } | 
|  |  | 
|  | namespace p0195r2_example { | 
|  | template<typename ...Ts> | 
|  | struct Overloader : Ts... { | 
|  | using Ts::operator() ...; | 
|  | }; | 
|  |  | 
|  | template<typename ...Ts> | 
|  | constexpr auto make_overloader(Ts &&...ts) { | 
|  | return Overloader<Ts...>{static_cast<Ts&&>(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}} | 
|  | } | 
|  | } |