使用模板来提高代码的抽象级别?

时间:2017-08-19 02:13:45

标签: c++ cpp-core-guidelines

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

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

根据上面的指南,这些例子在概念上是不好的,因为它错过了泛化的机会(受限于“可以递增”或“可以添加”的低级概念)。

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

2 个答案:

答案 0 :(得分:5)

糟糕的是(评论)概念。这些内容过于具体且与实施相关联,因为他们声明Incrementable<T>仅限于+=Simple_number<T> +=

它们提供了“算术”的正确概念,它提供了更完整的操作集++==,...

所以你可以用另一个实现替换一个实现。

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

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

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

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

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

答案 1 :(得分:0)

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

它有两个版本,一个带有二元仿函数,所以你可以在没有operator+的情况下求和。

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

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

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