// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s // C++1z [temp.local]p1: // Like normal (non-template) classes, class templates have an // injected-class-name (Clause 9). The injected-class-name can // be used as a template-name or a type-name. template<typename> char id; template<typename> struct TempType {}; template<template<typename> class> struct TempTemp {}; template<typename> void use(int&); // expected-note {{invalid explicitly-specified argument}} expected-note {{no known conversion}} template<template<typename> class> void use(float&); // expected-note 2{{no known conversion}} template<int> void use(char&); // expected-note 2{{invalid explicitly-specified argument}} template<typename T> struct A { template<typename> struct C {}; struct B : C<T> { // When it is used with a template-argument-list, A<int> *aint; typename B::template C<int> *cint; // as a template-argument for a template template-parameter, TempTemp<A> a_as_temp; TempTemp<B::template C> c_as_temp; // or as the final identifier in the elaborated-type-specifier of a friend // class template declaration, template<typename U> friend struct A; // it refers to the class template itself. // Otherwise, it is equivalent to the template-name followed by the // template-parameters of the class template enclosed in <>. A *aT; typename B::C *cT; TempType<A> a_as_type; TempType<typename B::C> c_as_type; friend struct A; friend struct B::C; void f(T &t) { use<A>(t); // expected-error {{no matching function}} if constexpr (&id<T> != &id<int>) use<B::template C>(t); // expected-error {{no matching function}} } }; }; template struct A<int>; template struct A<float>; template struct A<char>; // expected-note {{instantiation of}} template <typename T> struct X0 { X0(); ~X0(); X0 f(const X0&); }; // Test non-type template parameters. template <int N1, const int& N2, const int* N3> struct X1 { X1(); ~X1(); X1 f(const X1& x1a) { X1 x1b(x1a); return x1b; } }; // When it is used with a template-argument-list, it refers to the specified // class template specialization, which could be the current specialization // or another specialization. // FIXME: Test this clause. int i = 42; void test() { X0<int> x0; (void)x0; X1<42, i, &i> x1; (void)x1; } |