编程语言
首页 > 编程语言> > c – 有没有理由标准算法按价值取Lambda?

c – 有没有理由标准算法按价值取Lambda?

作者:互联网

参见英文答案 > Why the sequence-operation algorithms predicates are passed by copy?                                    3个
所以我在这里问了一个问题:Lambda Works on Latest Visual Studio, but Doesn’t Work Elsewhere我得到了回复,我的代码是实现定义的,因为标准的25.1 [algorithms.general] 10说:

Unless otherwise specified, algorithms that take function objects as arguments are permitted to copy
those function objects freely. Programmers for whom object identity is important should consider using a
wrapper class that points to a noncopied implementation object such as reference_wrapper<T>

我想知道为什么会这样?我们被告知我们整个生命中通过引用来获取对象,为什么标准是按值获取函数对象,更糟糕的是我的链接问题制作了这些对象的副本?这样做有什么我不明白的优点吗?

解决方法:

std假设函数对象和迭代器可以自由复制.

std :: ref提供了一种方法,使用兼容的operator()将函数对象转换为伪引用,该运算符使用引用而不是值语义.所以没有任何大价值的东西丢失了.

如果你一生都被教导过参考物品,那就重新考虑一下.除非有充分的理由,否则按值获取对象.关于价值观的推理要容易得多;引用是指向程序中任何位置的任何状态的指针.

传统的引用使用,作为指向本地对象的指针,在使用它的上下文中没有被任何其他活动引用引用,它不是某人读取您的代码,也不是编译器可以推测的.如果您以这种方式推理引用,它们不会为您的代码添加过多的复杂性.

但是如果你以这种方式对它们进行推理,那么当你的假设被违反时,你就会有错误,而且它们将是微妙的,粗暴的,意外的和可怕的.

一个典型的例子是当此参数和参数引用同一个对象时,break = break的数量.但是任何带有两个相同类型的引用或指针的函数都有相同的问题.

但即使一个引用也可能破坏您的代码.我们来看看排序.在伪代码中:

void sort( Iterator start, Iterator end, Ordering order )

现在,让我们订购一个参考:

void sort( Iterator start, Iterator end, Ordering const& order )

这个怎么样?

std::function< void(int, int) > alice;
std::function< void(int, int) > bob;
alice = [&]( int x, int y ) { std:swap(alice, bob); return x<y; };
bob = [&]( int x, int y ) { std:swap(alice, bob); return x>y; };

现在,调用sort(begin(vector),end(vector),alice).

每次<被称为,所提到的订单对象交换意义.现在这非常荒谬,但是当您使用const&和Ordering时,优化器必须考虑到这种可能性,并在订购代码的每次调用时将其排除在外! 你不会做上面的事情(实际上这个特定的实现是UB,因为它会违反std :: sort上的任何合理的要求);但编译器必须证明你每次遵循命令或调用它时都没有“喜欢那样”(在订购时更改代码)!这意味着不断重新加载秩序状态,或者内联并证明你做了非常疯狂的事情. 在采用按值时执行此操作会更难一个数量级(并且基本上需要像std :: ref之类的东西).优化器有一个函数对象,它是本地的,其状态是本地的.存储在其中的任何内容都是本地的,编译器和优化器知道谁可以合法地修改它. 您编写的每个函数都使用const&永远离开它的“局部范围”(比如称为C库函数)不能假设const&的状态.它回来后保持不变.它必须从指针指向的任何位置重新加载数据. 现在,除非有充分的理由,否则我确实说过价值.而且有很多好的理由;你的类型移动或复制非常昂贵,例如,这是一个很好的理由.您正在向其写入数据.你实际上希望它在你每次阅读时都要改变.等等. 但默认行为应该是按值传递.如果你有充分的理由,只能转向参考,因为成本是分散的,很难确定.

标签:c,lambda,algorithm,pass-by-reference,pass-by-value
来源: https://codeday.me/bug/20190929/1831472.html