1 | // RUN: %clang_cc1 -std=c++11 -verify %s |
2 | |
3 | template<typename ...T> struct X { |
4 | void f(int); |
5 | void f(...); |
6 | static int n; |
7 | }; |
8 | |
9 | template<typename T, typename U> using A = T; |
10 | |
11 | // These definitions are OK, X<A<T, decltype(...)>...> is equivalent to X<T...> |
12 | // so this defines the member of the primary template. |
13 | template<typename ...T> |
14 | void X<A<T, decltype(f(T()))>...>::f(int) {} // expected-error {{undeclared}} |
15 | |
16 | template<typename ...T> |
17 | int X<A<T, decltype(f(T()))>...>::n = 0; // expected-error {{undeclared}} |
18 | |
19 | struct Y {}; void f(Y); |
20 | |
21 | void g() { |
22 | // OK, substitution succeeds. |
23 | X<Y>().f(0); |
24 | X<Y>::n = 1; |
25 | |
26 | // Error, substitution fails; this should not be treated as a SFINAE-able |
27 | // condition, so we don't select X<void>::f(...). |
28 | X<void>().f(0); // expected-note {{instantiation of}} |
29 | X<void>::n = 1; // expected-note {{instantiation of}} |
30 | } |
31 | |