// RUN: %clang_cc1 -std=c++1z %s -verify // The same restrictions apply to the parameter-declaration-clause of a // deduction guide as in a function declaration. template struct A {}; A(void) -> A; // ok A(void, int) -> A; // expected-error {{'void' must be the first and only parameter if specified}} // We interpret this as also extending to the validity of redeclarations. It's // a bit of a stretch (OK, a lot of a stretch) but it gives desirable answers. A() -> A; // ok, redeclaration A() -> A; // expected-note {{previous}} A() -> A; // FIXME: "functions" is a poor term. expected-error {{functions that differ only in their return type cannot be overloaded}} template A(T) -> A; template A(T) -> A; // ok, can overload on return type (SFINAE applies) A(long) -> A; template A(long) -> A; // ok, non-template beats template as usual // (Pending DR) The template-name shall name a class template. template using B = A; // expected-note {{template}} B() -> B; // expected-error {{cannot specify deduction guide for alias template 'B'}} // FIXME: expected-error@-1 {{declarator requires an identifier}} template int C; C() -> int; // expected-error {{requires a type specifier}} template void D(); D() -> int; // expected-error {{requires a type specifier}} template typename TT> struct E { // expected-note 2{{template}} // FIXME: Should only diagnose this once! TT(int) -> TT; // expected-error 2{{cannot specify deduction guide for template template parameter 'TT'}} expected-error {{requires an identifier}} }; A(int) -> int; // expected-error {{deduced type 'int' of deduction guide is not a specialization of template 'A'}} template A(T) -> B; // expected-error {{deduced type 'B' (aka 'A') of deduction guide is not written as a specialization of template 'A'}} template A(T*) -> const A; // expected-error {{deduced type 'const A' of deduction guide is not a specialization of template 'A'}} // A deduction-guide shall be declared in the same scope as the corresponding // class template. namespace WrongScope { namespace { template struct AnonNS1 {}; // expected-note {{here}} AnonNS1(float) -> AnonNS1; // ok } AnonNS1(int) -> AnonNS1; // expected-error {{deduction guide must be declared in the same scope as template 'WrongScope::}} template struct AnonNS2 {}; // expected-note {{here}} namespace { AnonNS1(char) -> AnonNS1; // ok AnonNS2(int) -> AnonNS2; // expected-error {{deduction guide must be declared in the same scope as template 'WrongScope::AnonNS2'}} } namespace N { template struct NamedNS1 {}; // expected-note {{here}} template struct NamedNS2 {}; // expected-note {{here}} } using N::NamedNS1; NamedNS1(int) -> NamedNS1; // expected-error {{deduction guide must be declared in the same scope as template}} using namespace N; NamedNS2(int) -> NamedNS2; // expected-error {{deduction guide must be declared in the same scope as template}} struct ClassMemberA { template struct X {}; // expected-note {{here}} }; struct ClassMemberB : ClassMemberA { X(int) -> X; // expected-error {{deduction guide must be declared in the same scope as template 'WrongScope::ClassMemberA::X'}} }; template struct Local {}; void f() { Local(int) -> Local; // expected-error {{expected}} using WrongScope::Local; Local(int) -> Local; // expected-error {{expected}} } }