1 | // RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s |
2 | |
3 | // C++1z [temp.local]p1: |
4 | // Like normal (non-template) classes, class templates have an |
5 | // injected-class-name (Clause 9). The injected-class-name can |
6 | // be used as a template-name or a type-name. |
7 | |
8 | template<typename> char id; |
9 | |
10 | template<typename> struct TempType {}; |
11 | template<template<typename> class> struct TempTemp {}; |
12 | |
13 | template<typename> void use(int&); // expected-note {{invalid explicitly-specified argument}} expected-note {{no known conversion}} |
14 | template<template<typename> class> void use(float&); // expected-note 2{{no known conversion}} |
15 | template<int> void use(char&); // expected-note 2{{invalid explicitly-specified argument}} |
16 | |
17 | template<typename T> struct A { |
18 | template<typename> struct C {}; |
19 | struct B : C<T> { |
20 | // When it is used with a template-argument-list, |
21 | A<int> *aint; |
22 | typename B::template C<int> *cint; |
23 | |
24 | // as a template-argument for a template template-parameter, |
25 | TempTemp<A> a_as_temp; |
26 | TempTemp<B::template C> c_as_temp; |
27 | |
28 | // or as the final identifier in the elaborated-type-specifier of a friend |
29 | // class template declaration, |
30 | template<typename U> friend struct A; |
31 | // it refers to the class template itself. |
32 | |
33 | // Otherwise, it is equivalent to the template-name followed by the |
34 | // template-parameters of the class template enclosed in <>. |
35 | A *aT; |
36 | typename B::C *cT; |
37 | TempType<A> a_as_type; |
38 | TempType<typename B::C> c_as_type; |
39 | friend struct A; |
40 | friend struct B::C; |
41 | |
42 | void f(T &t) { |
43 | use<A>(t); // expected-error {{no matching function}} |
44 | if constexpr (&id<T> != &id<int>) |
45 | use<B::template C>(t); // expected-error {{no matching function}} |
46 | } |
47 | }; |
48 | }; |
49 | |
50 | template struct A<int>; |
51 | template struct A<float>; |
52 | template struct A<char>; // expected-note {{instantiation of}} |
53 | |
54 | template <typename T> struct X0 { |
55 | X0(); |
56 | ~X0(); |
57 | X0 f(const X0&); |
58 | }; |
59 | |
60 | // Test non-type template parameters. |
61 | template <int N1, const int& N2, const int* N3> struct X1 { |
62 | X1(); |
63 | ~X1(); |
64 | X1 f(const X1& x1a) { X1 x1b(x1a); return x1b; } |
65 | }; |
66 | |
67 | // When it is used with a template-argument-list, it refers to the specified |
68 | // class template specialization, which could be the current specialization |
69 | // or another specialization. |
70 | // FIXME: Test this clause. |
71 | |
72 | int i = 42; |
73 | void test() { |
74 | X0<int> x0; (void)x0; |
75 | X1<42, i, &i> x1; (void)x1; |
76 | } |
77 | |