为什么 STL 数值算法使用 'op' 而不是 'op='?
Why do STL numeric algorithms use 'op' rather than 'op='?
为什么 std::numeric
算法似乎更喜欢 op 而不是 op =?例如,这里是 std::accumulate
在 LLVM 中的实现:
template <class _InputIterator, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
_Tp
accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
{
for (; __first != __last; ++__first)
__init = __init + *__first;
return __init;
}
如果使用 +=
运算符实现,这不会更 efficient/less verbose/better 吗?
它可能会更有效率,而且显然不会那么冗长。
以这种方式做事的通常原因是尽量减少对基础类型的要求。如果您使用 +=
,则基础类型必须支持 +=
。对于像 int
这样微不足道并且已经存在的东西,但是对于您定义的 class,完全有可能定义 +
和 =
,而不是复合 +=
(在这种情况下,使用 +=
的代码显然会失败)。
在我看来,主要原因是您可以使用标准功能对象 std::plus
并获得与 operator +
相同的结果,就像使用 operator <
和标准功能对象一样std::less
在像 std::sort
.
这样的排序算法中
标准中是这样定义的……
标准是根据 +
定义的,而不是 +=
:
26.7.2 Accumulate [accumulate]
template <class InputIterator, class T>
T accumulate(InputIterator first, InputIterator last, T init);
template <class InputIterator, class T, class BinaryOperation>
T accumulate(InputIterator first, InputIterator last, T init,
BinaryOperation binary_op);
Effects: Computes its result by initializing the accumulator acc
with the initial value init
and then modifies it with acc = acc + *i
or acc = binary_op(acc, *i)
for every iterator i
in the range
[first,last)
in order.
其他数值算法也是如此。
…标准基于STL…
但这就是为什么他们现在实施的原因。但是,要了解原始原因,需要 go further down the rabbit hole:
Requirements on types
For the first version, the one that takes two arguments:
InputIterator
is a model of Input Iterator.
T
is a model of Assignable.
- If
x
is an object of type T
and y
is an object of InputIterator
's value
type, then x + y
is defined.
- The return type of
x + y
is convertible to T
.
…STL 是由…创建的?
那么,这是为什么呢?让我们问问 Alexander Stepanov,STL 背后的思想:
[A] user has asked a [question] on Whosebug two days ago concerning
the implementation and formulation of numerical algorithms like
accumulate
or inner_product
, which are defined in terms of +
instead of +=
(section 26.7 in ISO C++11).
I've tried to find some rationale behind the decision, but even the
version on SGI's page doesn't mention anything regarding this
particular choice of the operator.
Was the choice of the operator (a = a + b instead of a += b) only
based on your personal preference, as some comments assume? Was a+b
the more natural way to write the operation back then? Or was it
simply a matter of symmetry between a = a +b and a = bin_op(a,b)?
-- [Zeta]
现在,在您阅读他的回答之前,请记住他大约 30 年前开始编写通用库,他和 Meng Lee 的初始文档 The Standard Template Library 将在今年 10 月迎来 20 周年纪念日。话不多说,我给出他的答案:
I suspect that it was a matter of symmetry between a = a + b and a = bin_op(a,b), but I really do not remember. I should have written a rationale document stating all the reasoning between different design choices in STL, but I did not. Sorry.
(如果 Stepanov 偶然读到了这篇文章:再次感谢您的回答!)
我 个人 认为 Common Lisp reduce
的启发是另一个因素,但这只是推测。
从中可以学到什么?
有时,标准的决定是基于个人喜好和优雅。例如,如果 Stroustrup 编写了 STL,他就会有 "strongly prefer[ed] the use of a+=b as being a more direct expression of intent and typically faster than a=a+b"。不过不得不承认,a = a+b 和 a=bin_op(a,b) 的对称性自有其美。
话虽这么说,a+=b
和 a=a+b
争议将引发挑战:
This issue will become very important when we define standard concepts, and I do not know how it will be resolved. [Stroustrup; also thanks to him for answering my question!]
就这些了,我希望您喜欢 C++ 的一点历史。
使用 + 而不是 += 的原因有很多。
一个。因为这是正确的方法。 Accumulate is fold,一个作用于+而非+=的函子(将函数映射到函数的函数)。为什么 + 而不是 +=?因为 += 不是数学函数。
乙。它更有效(在现代编译器上,在所有原始类型和精心设计的对象上)。 += 对于 30 年前的编译器来说可能更快,但现在 + 更快,除非你正在积累的是一个具有太多 OO 的可怕对象。对象生命周期分析在 const 对象上比在引用上更容易完成。
C。它更清楚。这个理由与(A)确实没有本质区别。 + 比 += 更清晰。清晰胜过冗长。
我想,事实是重用。 STL 的其余部分使用二进制 operators 而 +=
是一个 action。所以有 plus
、multiplies
等,但没有 add_action
(比方说)。运算符和操作是完全对称的,但如果您实施超过 90 种算法,在某些时候您可能不得不停止添加新概念并发布它。
Alex 曾说过,他从未打算让他的 STL 成为所有 STL 开发的终结,尤其是。因为标准化版本只包含他最初提议的一小部分。这是一个明显的扩展。
为什么 std::numeric
算法似乎更喜欢 op 而不是 op =?例如,这里是 std::accumulate
在 LLVM 中的实现:
template <class _InputIterator, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
_Tp
accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
{
for (; __first != __last; ++__first)
__init = __init + *__first;
return __init;
}
如果使用 +=
运算符实现,这不会更 efficient/less verbose/better 吗?
它可能会更有效率,而且显然不会那么冗长。
以这种方式做事的通常原因是尽量减少对基础类型的要求。如果您使用 +=
,则基础类型必须支持 +=
。对于像 int
这样微不足道并且已经存在的东西,但是对于您定义的 class,完全有可能定义 +
和 =
,而不是复合 +=
(在这种情况下,使用 +=
的代码显然会失败)。
在我看来,主要原因是您可以使用标准功能对象 std::plus
并获得与 operator +
相同的结果,就像使用 operator <
和标准功能对象一样std::less
在像 std::sort
.
标准中是这样定义的……
标准是根据 +
定义的,而不是 +=
:
26.7.2 Accumulate
[accumulate]
template <class InputIterator, class T> T accumulate(InputIterator first, InputIterator last, T init); template <class InputIterator, class T, class BinaryOperation> T accumulate(InputIterator first, InputIterator last, T init, BinaryOperation binary_op);
Effects: Computes its result by initializing the accumulator
acc
with the initial valueinit
and then modifies it withacc = acc + *i
or acc = binary_op(acc, *i)
for every iteratori
in the range[first,last)
in order.
其他数值算法也是如此。
…标准基于STL…
但这就是为什么他们现在实施的原因。但是,要了解原始原因,需要 go further down the rabbit hole:
Requirements on types
For the first version, the one that takes two arguments:
InputIterator
is a model of Input Iterator.T
is a model of Assignable.- If
x
is an object of typeT
andy
is an object ofInputIterator
'svalue
type, thenx + y
is defined.- The return type of
x + y
is convertible toT
.
…STL 是由…创建的?
那么,这是为什么呢?让我们问问 Alexander Stepanov,STL 背后的思想:
[A] user has asked a [question] on Whosebug two days ago concerning the implementation and formulation of numerical algorithms like
accumulate
orinner_product
, which are defined in terms of+
instead of+=
(section 26.7 in ISO C++11).I've tried to find some rationale behind the decision, but even the version on SGI's page doesn't mention anything regarding this particular choice of the operator.
Was the choice of the operator (a = a + b instead of a += b) only based on your personal preference, as some comments assume? Was a+b the more natural way to write the operation back then? Or was it simply a matter of symmetry between a = a +b and a = bin_op(a,b)?
-- [Zeta]
现在,在您阅读他的回答之前,请记住他大约 30 年前开始编写通用库,他和 Meng Lee 的初始文档 The Standard Template Library 将在今年 10 月迎来 20 周年纪念日。话不多说,我给出他的答案:
I suspect that it was a matter of symmetry between a = a + b and a = bin_op(a,b), but I really do not remember. I should have written a rationale document stating all the reasoning between different design choices in STL, but I did not. Sorry.
(如果 Stepanov 偶然读到了这篇文章:再次感谢您的回答!)
我 个人 认为 Common Lisp reduce
的启发是另一个因素,但这只是推测。
从中可以学到什么?
有时,标准的决定是基于个人喜好和优雅。例如,如果 Stroustrup 编写了 STL,他就会有 "strongly prefer[ed] the use of a+=b as being a more direct expression of intent and typically faster than a=a+b"。不过不得不承认,a = a+b 和 a=bin_op(a,b) 的对称性自有其美。
话虽这么说,a+=b
和 a=a+b
争议将引发挑战:
This issue will become very important when we define standard concepts, and I do not know how it will be resolved. [Stroustrup; also thanks to him for answering my question!]
就这些了,我希望您喜欢 C++ 的一点历史。
使用 + 而不是 += 的原因有很多。
一个。因为这是正确的方法。 Accumulate is fold,一个作用于+而非+=的函子(将函数映射到函数的函数)。为什么 + 而不是 +=?因为 += 不是数学函数。
乙。它更有效(在现代编译器上,在所有原始类型和精心设计的对象上)。 += 对于 30 年前的编译器来说可能更快,但现在 + 更快,除非你正在积累的是一个具有太多 OO 的可怕对象。对象生命周期分析在 const 对象上比在引用上更容易完成。
C。它更清楚。这个理由与(A)确实没有本质区别。 + 比 += 更清晰。清晰胜过冗长。
我想,事实是重用。 STL 的其余部分使用二进制 operators 而 +=
是一个 action。所以有 plus
、multiplies
等,但没有 add_action
(比方说)。运算符和操作是完全对称的,但如果您实施超过 90 种算法,在某些时候您可能不得不停止添加新概念并发布它。
Alex 曾说过,他从未打算让他的 STL 成为所有 STL 开发的终结,尤其是。因为标准化版本只包含他最初提议的一小部分。这是一个明显的扩展。