我想我不明白下面5个模板化函数之间的区别,希望有人能解释。什么时候应该使用每个?
前2个没有默认模板参数,但后2个有默认模板参数。第一个和第三个将comp
的默认参数设置为default_comparer<data_t>()
,但是第二个和第四个不设置。最后一个似乎没用,因为从未使用过默认值。
template<typename data_t>
struct default_comparer {
bool operator()(const data_t& d1, const data_t& d2) const
{
return d1 < d2;
}
};
第一个
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
}
第二个
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
}
第三名
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
}
第四名
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
}
第五名
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
}
在大多数情况下,第四版是合理的版本。
对于前两个版本,除非用户为comparer_t
明确提供模板参数,否则将不使用默认参数,因为模板参数推导发生在插入默认参数之前;换句话说,出于模板参数推导的目的,不考虑默认参数。
当用户显式提供comparer_t
模板参数时,第三和第四版本之间的区别变得明显。在这种情况下,这些版本的默认参数会有所不同-第三版本需要从default_comparer<data_t>
进行转换,可能会导致错误。
第五个版本与假设版本之间既未提供默认模板参数也未提供默认参数的区别在于,前者允许将提供的默认模板参数用作后备,以防推断失败(例如,当用户提供{}
作为comp
的参数,但不提供comparer_t
的模板参数。]
顺便说一句,请注意,术语comparator比comparer更常用。