使用模板来提高代码的抽象层次?

Use of templates to raise the level of abstraction of code?

我正在阅读 T.1 的 CppCoreGuidelines,并且有以下示例

示例 1

template<typename T>
    // requires Incrementable<T>
T sum1(vector<T>& v, T s)
{
    for (auto x : v) s += x;
    return s;
}

示例 2

template<typename T>
    // requires Simple_number<T>
T sum2(vector<T>& v, T s)
{
    for (auto x : v) s = s + x;
    return s;
}

根据上面的指南,示例在概念上是错误的,因为它错过了概括的机会(仅限于“可以增加”或“可以添加”的低级概念)。

如何表达上述模板才能被称为好的通用模板?

不好的地方在于(评论的)概念。它们太具体并且与实现相关联,因为它们声明 Incrementable<T> 仅限制为运算符 +=Simple_number<T> 仅适用于 +=.

他们提供了正确的"Arithmetic"概念,提供了一套更完整的操作++==, ...

因此您可以用一种实现替换另一种实现。

更好的方法是将 vector<T> 替换为“range_view<T>”。

这里关注的不是实现,而是概念

STL 中的某些算法依赖于 operator == 的存在但不需要 operator !=,或者需要存在 operator < 而不是 operator >,这使得它们不够通用。

Orderable<T> 的概念比 HaveLess<T> 更通用。

大多数算法依赖于类型的某些要求,但它是否应该具有逻辑对应部分

标准库有很好的实现:http://en.cppreference.com/w/cpp/algorithm/accumulate

它有两个版本,一个采用二元函子,这样你就可以在没有 operator+ 的情况下求和。

它需要迭代器,因此您可以对任何可迭代容器求和,而不仅仅是向量。

它允许结果类型不同于容器的值类型。例如,您可能希望将 vector<float> 的总和存储在 double 中以提高精度。

它也永远不会复制值,这比问题中基于范围的 for(auto) 循环可以说的要多。