Reputation: 31
I have the following piece of code which compiles fine:
template <typename T>
struct A {T t;};
template <typename T> // 1
A(T) -> A<T>; // function template declaration with trailing return type compiles fine.
But the following variations of the same function declaration do not compile:
template <typename T> // 2
auto A(T) -> A<T>; // error: redefinition of 'A' as different kind of symbol
template <typename T> // 3
A<T> A(T); // error: redefinition of 'A' as different kind of symbol
please help me in understanding the rationale behind why those didn't compile
Upvotes: 1
Views: 558
Reputation: 66210
// function template declaration with trailing return type compiles fine.
template <typename T> // 1
A(T) -> A<T>; // function template declaration with trailing return type compiles fine.
Not exactly.
For a function declaration with explicit trailing return type, you have to add auto
before the name of the function.
Your "1" code example it's a new C++17 user defined deduction guide (see this page for more information).
Given your template A
class, you're saying the compiler that when you define a variable as follows
A a{42l};
you're defining a A<long>
variable, because the type of the template parameter is deduced from the argument of the constructor (42l
).
About following codes
template <typename T> // 2
auto A(T) -> A(T); // error: use of class template 'A' requires template arguments
Now you're using correctly auto
before the name, so you're declaring a function; unfortunately the name can't be A
(it's the name of a struct) and the return type can't be A(T)
(maybe A<T>
)
template <typename T> // 3
A<T> A(T); // error: redefinition of 'A' as different kind of symbol
Now you're correctly declaring a template function returning an A<T>
but remain the other problem: the name can't be A
(it's the name of a struct)
Upvotes: 3