Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is no deduction for template parameters only used as return type?

If I do not use tempate parameter (type) in a function argument list -> only as return type, then there is no deduction:

template <typename T>
T zero() { return 0; }

int main()
{
    int x = zero();
}

gives:

a.cpp:15:18: error: no matching function for call to ‘zero()’
     int x = zero();
                  ^
a.cpp:11:3: note: candidate: ‘template<class T> T zero()’
 T zero() { return 0; }
   ^~~~
a.cpp:11:3: note:   template argument deduction/substitution failed:
a.cpp:15:18: note:   couldn't deduce template parameter ‘T’
     int x = zero();

The only way to compile, is to specify the template type in angle brackets:

template <typename T>
T zero() { return 0; }

int main()
{
    int x = zero<int>();
}
  1. So my question is, why g++ can deduce the type from argument list of template function, but cannot deduce it from return type (which is also known for compiler when compiling main, so it knows the type).

  2. providing the type in angle brackets for template function is then arbitrary (because of deduction), when the template function uses template types in its argument list? So as a good practise, should I always provided the type in curly braces, no matter how the function is declared?

The second question is not readable much. Put it in simple words -> should I use foo<T>(arg, ...) (provide the type) everytime, no matter the function declaration? Even if it can be deduced by the compiler, but I will provided the type anyway for good practise?

like image 663
milanHrabos Avatar asked Dec 13 '22 08:12

milanHrabos


1 Answers

Generally it is not possible to deduce function based on its return type. But if you use automatic types conversion c++ feature then you could achieve what you need:

template <typename T>
T zero() { return 1; }

template <>
float zero<float>() { return 3.0f; }

struct Zero
{
    template<typename T>
    operator T()
    {
        return zero<T>();
    }
};

int main()
{
    int x = Zero();
    float y = Zero();
    return x + y;
}

First you create temporary object Zero(), and during assigment we use conversion operator to execute correct specialization of zero template function.

like image 166
AdamF Avatar answered Dec 15 '22 22:12

AdamF