Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ default parameter in template not allowed?

Tags:

c++

In my C++ code, I wrote like this:

template <typename T, typename Pred>
inline const T BestOfTwo(const T& lhs, const T& rhs, Pred p = std::less<T>())
{
    return p(lhs, rhs) ? lhs : rhs;
}

But this didn't work when I called BestOfTwo(3, 5). The compiler told me that no instance of overload matched. So now I have to write it like this:

template <typename T, typename Pred = std::less<T> >
inline const T BestOfTwo(const T& lhs, const T& rhs, Pred p = Pred())
{
    return p(lhs, rhs) ? lhs : rhs;
}

And this worked with no error when I called BestOfTwo(3, 5). But I think the previous style is more convenient and I didn't figure out where it went wrong. What are some suggestions?

like image 990
Philip Zhang Avatar asked Dec 22 '14 14:12

Philip Zhang


People also ask

Can template have default parameters?

You cannot give default arguments to the same template parameters in different declarations in the same scope. The compiler will not allow the following example: template<class T = char> class X; template<class T = char> class X { };

Can default argument be used with the template class?

Can default arguments be used with the template class? Explanation: The template class can use default arguments.

Can we pass Nontype parameters to templates?

Template non-type arguments in C++ It is also possible to use non-type arguments (basic/derived data types) i.e., in addition to the type argument T, it can also use other arguments such as strings, function names, constant expressions, and built-in data types.

How long template parameters will be valid?

3. What is the validity of template parameters? Explanation: Template parameters are valid inside a block only i.e. they have block scope.


2 Answers

Only the second version is correct (if you don't want to specify the Pred parameter manually), but only since C++11. There is already an answer from Angew that clarify why the first version is incorrect, without specification of the Pred parameter.

If you cannot use C++11 you should write two overloads (one with Pred and one without, that use std::less), since default template parameters for function templates are explicitly forbidden in C++98.

template<typename T, typename Pred>
inline const T BestOfTwo(const T& lhs, const T& rhs, Pred p = Pred())
{
   //
}

template<typename T>
inline const T BestOfTwo(const T& lhs, const T& rhs)
{
   return BestOfTwo<T, std::less<T> >(lhs, rhs);
}
like image 155
ForEveR Avatar answered Sep 29 '22 15:09

ForEveR


The first version would work if you specified the template arguments explicitly:

BestOfTwo<int, std::less<int>>(3, 5)

The reason is that default function arguments cannot be used to deduce the type for a template parameter.

like image 20
Angew is no longer proud of SO Avatar answered Sep 29 '22 17:09

Angew is no longer proud of SO