gpt4 book ai didi

c++ - 为什么序列操作算法谓词是通过拷贝传递的?

转载 作者:可可西里 更新时间:2023-11-01 17:59:58 26 4
gpt4 key购买 nike

我想知道为什么仿函数通过复制传递给 algorithm功能:

template <typename T> struct summatory
{
summatory() : result(T()) {}

void operator()(const T& value)
{ result += value; std::cout << value << "; ";};

T result;
};

std::array<int, 10> a {{ 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 }};
summatory<int> sum;

std::cout << "\nThe summation of: ";
std::for_each(a.begin(), a.end(), sum);
std::cout << "is: " << sum.result;

我期待以下输出:

The summation of: 1; 1; 2; 3; 5; 8; 13; 21; 34; 55; is: 143

但是 sum.result 包含 0,这是 ctor 中分​​配的默认值。实现所需行为的唯一方法是捕获 for_each 的返回值:

sum = std::for_each(a.begin(), a.end(), sum);
std::cout << "is: " << sum.result;

发生这种情况是因为仿函数通过复制传递给 for_each而不是引用:

template< class InputIt, class UnaryFunction >
UnaryFunction for_each( InputIt first, InputIt last, UnaryFunction f );

所以外部仿函数保持不变,而内部仿函数(它是外部仿函数的拷贝)被更新并在执行算法(live demo)后返回,所以结果被复制(或移动)完成所有操作后再次


这样做一定有充分的理由,但我并没有真正意识到这种设计的基本原理,所以我的问题是:

  • 为什么序列运算算法的谓词通过复制而不是引用传递?
  • 与引用传递方法相比,复制传递方法有何优势?

最佳答案

这主要是出于历史原因。在 98 年,当整个算法的东西被纳入标准引用时,出现了各种各样的问题。这最终通过 C++03 及更高版本的核心和库 DR 得到了解决。明智的 ref-wrappers 和实际工作的绑定(bind)也只在 TR1 中出现。

那些尝试在早期 C++98 中使用具有使用 ref 参数或返回的函数的算法的人可以记忆起各种麻烦。自行编写的算法也容易遇到可怕的“引用引用”问题。

按值传递至少工作得很好,几乎不会产生很多问题——而且 boost 很早就有 ref 和 cref 来帮助您找出需要调整的地方。

关于c++ - 为什么序列操作算法谓词是通过拷贝传递的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42721683/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com