模板中的C ++默认参数不允许?

时间:2014-12-22 14:55:56

标签: c++

在我的C ++代码中,我写的是这样的:

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;
}

但是当我打电话给 BestOfTwo(3,5)时,这不起作用。编译器告诉我没有匹配的重载实例。所以现在我必须这样写:

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;
}

当我打电话给 BestOfTwo(3,5)时,这没有任何错误。但我认为之前的风格更方便,我也没想出它出错的地方。有什么建议吗?

2 个答案:

答案 0 :(得分:12)

只有第二个版本是正确的(如果您不想手动指定Pred参数),但仅限于C ++ 11。 Angew已经有一个答案澄清了为什么第一个版本不正确,没有指定Pred参数。

如果您不能使用C ++ 11,您应该编写两个重载(一个使用Pred,一个不使用std::less),因为在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);
}

答案 1 :(得分:10)

如果明确指定模板参数,第一个版本将起作用:

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

原因是默认函数参数不能用于推导模板参数的类型。