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>; // expected-note {{previous}} 7 A(void, int) -> A<int>; // expected-error {{'void' must be the first and only parameter if specified}} 8 9 A() -> A<int>; // expected-error {{redeclaration of deduction guide}} 10 // expected-note@-1 {{previous}} 11 12 A() -> A<int>; // expected-note {{previous}} 13 // expected-error@-1 {{redeclaration of deduction guide}} 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 {{a type specifier is required}} 28 template<typename T> void D(); 29 D() -> int; // expected-error {{a type specifier is required}} 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<T>') 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 59 using namespace N; 60 NamedNS2(int) -> NamedNS2<int>; // expected-error {{deduction guide must be declared in the same scope as template}} 61 struct ClassMemberA { 62 template<typename T> struct X {}; // expected-note {{here}} 63 }; 64 struct ClassMemberB : ClassMemberA { 65 X(int) -> X<int>; // expected-error {{deduction guide must be declared in the same scope as template 'WrongScope::ClassMemberA::X'}} 66 }; 67 template<typename T> struct Local {}; 68 void f() { 69 Local(int) -> Local<int>; // expected-error {{expected}} 70 using WrongScope::Local; 71 Local(int) -> Local<int>; // expected-error {{expected}} 72 } 73 } 74