1 | // RUN: %clang_cc1 -std=c++1z %s -verify |
2 | |
3 | // The same restrictions apply to the parameter-declaration-clause of a |
4 | // deduction guide as in a function declaration. |
5 | template<typename T> struct A {}; |
6 | A(void) -> A<int>; // ok |
7 | A(void, int) -> A<int>; // expected-error {{'void' must be the first and only parameter if specified}} |
8 | |
9 | // We interpret this as also extending to the validity of redeclarations. It's |
10 | // a bit of a stretch (OK, a lot of a stretch) but it gives desirable answers. |
11 | A() -> A<int>; // ok, redeclaration |
12 | |
13 | A() -> A<int>; // expected-note {{previous}} |
14 | A() -> A<float>; // FIXME: "functions" is a poor term. expected-error {{functions that differ only in their return type cannot be overloaded}} |
15 | |
16 | template<typename T> A(T) -> A<typename T::foo>; |
17 | template<typename T> A(T) -> A<typename T::bar>; // ok, can overload on return type (SFINAE applies) |
18 | |
19 | A(long) -> A<int>; |
20 | template<typename T = int> A(long) -> A<char>; // ok, non-template beats template as usual |
21 | |
22 | // (Pending DR) The template-name shall name a class template. |
23 | template<typename T> using B = A<T>; // expected-note {{template}} |
24 | B() -> B<int>; // expected-error {{cannot specify deduction guide for alias template 'B'}} |
25 | // FIXME: expected-error@-1 {{declarator requires an identifier}} |
26 | template<typename T> int C; |
27 | C() -> int; // expected-error {{requires a type specifier}} |
28 | template<typename T> void D(); |
29 | D() -> int; // expected-error {{requires a type specifier}} |
30 | template<template<typename> typename TT> struct E { // expected-note 2{{template}} |
31 | // FIXME: Should only diagnose this once! |
32 | TT(int) -> TT<int>; // expected-error 2{{cannot specify deduction guide for template template parameter 'TT'}} expected-error {{requires an identifier}} |
33 | }; |
34 | |
35 | A(int) -> int; // expected-error {{deduced type 'int' of deduction guide is not a specialization of template 'A'}} |
36 | template<typename T> A(T) -> B<T>; // expected-error {{deduced type 'B<T>' (aka 'A<type-parameter-0-0>') of deduction guide is not written as a specialization of template 'A'}} |
37 | template<typename T> A(T*) -> const A<T>; // expected-error {{deduced type 'const A<T>' of deduction guide is not a specialization of template 'A'}} |
38 | |
39 | // A deduction-guide shall be declared in the same scope as the corresponding |
40 | // class template. |
41 | namespace WrongScope { |
42 | namespace { |
43 | template<typename T> struct AnonNS1 {}; // expected-note {{here}} |
44 | AnonNS1(float) -> AnonNS1<float>; // ok |
45 | } |
46 | AnonNS1(int) -> AnonNS1<int>; // expected-error {{deduction guide must be declared in the same scope as template 'WrongScope::}} |
47 | template<typename T> struct AnonNS2 {}; // expected-note {{here}} |
48 | namespace { |
49 | AnonNS1(char) -> AnonNS1<char>; // ok |
50 | AnonNS2(int) -> AnonNS2<int>; // expected-error {{deduction guide must be declared in the same scope as template 'WrongScope::AnonNS2'}} |
51 | } |
52 | namespace N { |
53 | template<typename T> struct NamedNS1 {}; // expected-note {{here}} |
54 | template<typename T> struct NamedNS2 {}; // expected-note {{here}} |
55 | } |
56 | using N::NamedNS1; |
57 | NamedNS1(int) -> NamedNS1<int>; // expected-error {{deduction guide must be declared in the same scope as template}} |
58 | using namespace N; |
59 | NamedNS2(int) -> NamedNS2<int>; // expected-error {{deduction guide must be declared in the same scope as template}} |
60 | struct ClassMemberA { |
61 | template<typename T> struct X {}; // expected-note {{here}} |
62 | }; |
63 | struct ClassMemberB : ClassMemberA { |
64 | X(int) -> X<int>; // expected-error {{deduction guide must be declared in the same scope as template 'WrongScope::ClassMemberA::X'}} |
65 | }; |
66 | template<typename T> struct Local {}; |
67 | void f() { |
68 | Local(int) -> Local<int>; // expected-error {{expected}} |
69 | using WrongScope::Local; |
70 | Local(int) -> Local<int>; // expected-error {{expected}} |
71 | } |
72 | } |
73 | |