Search code examples
c++templatesc++17template-argument-deductionfunction-templates

Question about trailing return type in C++17


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


Solution

  • // 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)