I don't think I understand what the difference is between the 5 templated functions below, and hope that someone can explain. When should each one be used?
The first 2 has no default template parameters, but the last 2 do. The first and third ones set the default argument for comp
to default_comparer<data_t>()
, but the second and four ones do not. The last one seems useless in that the default is never used.
template<typename data_t>
struct default_comparer {
bool operator()(const data_t& d1, const data_t& d2) const
{
return d1 < d2;
}
};
FIRST ONE
template<typename data_t, typename comparer_t>
pair partition(std::vector<data_t>& list, size_t pivot_idx, size_t start, size_t end,
const comparer_t& comp = default_comparer<data_t>())
{
//do stuff
}
SECOND ONE
template<typename data_t, typename comparer_t>
pair partition(std::vector<data_t>& list, size_t pivot_idx, size_t start, size_t end,
const comparer_t& comp = comparer_t())
{
//do stuff
}
THIRD ONE
template<typename data_t, typename comparer_t = default_comparer<data_t>>
pair partition(std::vector<data_t>& list, size_t pivot_idx, size_t start, size_t end,
const comparer_t& comp = default_comparer<data_t>())
{
//do stuff
}
FOURTH ONE
template<typename data_t, typename comparer_t = default_comparer<data_t>>
pair partition(std::vector<data_t>& list, size_t pivot_idx, size_t start, size_t end,
const comparer_t& comp = comparer_t())
{
//do stuff
}
FIFTH ONE
template<typename data_t, typename comparer_t = default_comparer<data_t>>
pair partition(std::vector<data_t>& list, size_t pivot_idx, size_t start, size_t end,
const comparer_t& comp)
{
//do stuff
}
In most circumstances, the fourth version is the reasonable version.
For the first two versions, the default argument will not be used unless the user explicitly provides a template argument for comparer_t
, because template argument deduction happens before default arguments are plugged in; in other words, default arguments are not considered for the purpose of template argument deduction.
The difference between the third and fourth versions becomes evident when the user explicitly provides the comparer_t
template argument. In this case, the default arguments of the these versions differ — the third version requires a conversion from default_comparer<data_t>
, possibly resulting in an error.
The difference between the fifth version and the hypothetical version in which neither default template arguments nor default arguments are given is that the former allows the provided default template argument to be used as a fallback in case deduction fails for it (for example, when the user provides {}
as the argument to comp
and does not provide a template argument for comparer_t
).
Incidentally, please note that the term comparator is more commonly used than comparer.