Reputation: 627
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?
Upvotes: 12
Views: 2082
Reputation: 55887
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);
}
Upvotes: 12
Reputation: 171117
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.
Upvotes: 10