【问题标题】:Use of templates to raise the level of abstraction of code?使用模板来提高代码的抽象级别?
【发布时间】:2017-08-19 02:13:44
【问题描述】:

我正在浏览 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;
}

根据上述指南,这些示例在概念上很糟糕,因为它错过了泛化的机会(仅限于“可以增加”或“可以添加”的低级概念)。

如何表达上述模板才能称得上是好的泛化模板?

【问题讨论】:

  • 为什么不使用s = std::accumulate(std::begin(v), std::end(v), s)?适用于任何标准容器(和原版 C 样式数组),不依赖于 sv 的元素是同一类型(尽管需要定义添加它们)。我建议它比您的任何一个示例都更通用 - std::accumulate() 可用于其他用途。

标签: c++ cpp-core-guidelines


【解决方案1】:

坏事在于(评论的)概念。它们过于具体并且与实现相关,因为它们声明 Incrementable&lt;T&gt; 仅限制为运算符 +=Simple_number&lt;T&gt; 仅适用于 +=

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

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

vector&lt;T&gt; 替换为“range_view&lt;T&gt;”会更好。

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

一些来自 STL 的算法依赖于operator == 的存在但不需要operator !=,或者需要operator &lt; 的存在而不是operator &gt;,这使得它们不够通用。

Orderable&lt;T&gt; 的概念比HaveLess&lt;T&gt; 更通用。

大多数算法依赖于类型的一些要求,但它应该有逻辑上的对应

【讨论】:

  • 那么对于模板,哪个更适合 += 或 + 和 = ..或者它没有区别?
【解决方案2】:

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

它有两个版本,一个采用二进制函子,因此您可以在没有operator+ 的情况下求和。

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

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

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

【讨论】:

  • 如果你按照OP给出的链接,批评的不是那个部分,而是概念。
  • 我只是对文本感到困惑,除了 += 和 + , = 之外,我们还能用什么其他方式来表示 sum
猜你喜欢
  • 2014-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-24
相关资源
最近更新 更多