为什么std :: plus是一个类模板?

时间:2015-10-14 17:26:27

标签: c++

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::stringconst 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>具有完全相同的功能,但避免使用模板。那么为什么不选择这个呢?课堂模板背后的逻辑/动机是什么? (它违反了规则“尽可能简化”)

2 个答案:

答案 0 :(得分:3)

在早期版本的C ++中,不允许使用模板化成员函数(即使是那些允许模板化类和自由函数的函数)。这意味着像std::plus这样的仿函数必须完全专业化,而不是将特化推迟到运算符。

答案 1 :(得分:1)

虽然我今天已经因为第二次猜测原因而受到惩罚,但我仍然敢于表达我的观点:)

我认为,std::plus是一个模板,因此可以对其进行特定处理,而+以外的其他内容可用于未定义+的类型。