C ++仿函数std::plus
的实现方式与
template<typename T>
struct plus
{
constexpr T operator+(const T& lhs, const T& rhs) const
{ return lhs+rhs; }
};
但也有专业化
template<>
struct plus<void>
{
template< class T, class U>
constexpr auto operator()(T&& lhs, U&& rhs) const
-> decltype(std::forward<T>(lhs) + std::forward<U>(rhs))
{ return std::forward<T>(lhs) + std::forward<U>(rhs); }
};
只要T+U
被定义(例如std::string
和const char*
),就可以对任何类型(甚至是不同类型)进行操作。
我想知道为什么struct std::plus
没有被定义为具有现有std::plus<void>
功能的非模板?是否有任何可能的应用程序无法通过此类实现提供服务?
当然,这可能有历史原因(因此无法更改)。但如果这是唯一的原因,是不是可以将模板参数更改为默认为void
?
template<typename T=void> struct plus;
修改。我刚刚意识到根据cppreference plus<T>
默认为plus<void>
,因为C ++ 14。
可以说,plus<void>::operator+
无法在C98 ++中实现,但以下内容可以
struct plus
{
template<class T>
T operator()(const T&lhs, const T&rhs) const
{ return lhs + rhs; }
};
与plus<T>
具有完全相同的功能,但避免使用模板。那么为什么不选择这个呢?课堂模板背后的逻辑/动机是什么? (它违反了规则“尽可能简化”)
答案 0 :(得分:3)
在早期版本的C ++中,不允许使用模板化成员函数(即使是那些允许模板化类和自由函数的函数)。这意味着像std::plus
这样的仿函数必须完全专业化,而不是将特化推迟到运算符。
答案 1 :(得分:1)
虽然我今天已经因为第二次猜测原因而受到惩罚,但我仍然敢于表达我的观点:)
我认为,std::plus
是一个模板,因此可以对其进行特定处理,而+
以外的其他内容可用于未定义+
的类型。