将std :: transform与std :: back_inserter一起使用是否有效? [英] Is it valid to use std::transform with std::back_inserter?

查看:600
本文介绍了将std :: transform与std :: back_inserter一起使用是否有效?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Cppreference具有以下示例代码,用于 std :: transform

Cppreference has this example code for std::transform:

std::vector<std::size_t> ordinals;
std::transform(s.begin(), s.end(), std::back_inserter(ordinals),
               [](unsigned char c) -> std::size_t { return c; });

但是它也说:


std :: transform 不保证按顺序应用 unary_op binary_op 。要将函数按顺序应用于序列或将函数修改序列的元素,请使用 std :: for_each

std::transform does not guarantee in-order application of unary_op or binary_op. To apply a function to a sequence in-order or to apply a function that modifies the elements of a sequence, use std::for_each.

大概是为了允许并行实现。但是 std :: transform 的第三个参数是 LegacyOutputIterator 对于 ++ r 具有以下后置条件:

This is presumably to allow parallel implementations. However the third parameter of std::transform is a LegacyOutputIterator which has the following postcondition for ++r:


此操作后, r 不需要是可递增的,并且以前值<$ c的任何副本$ c> r 不再需要是可解除引用或可递增的。

After this operation r is not required to be incrementable and any copies of the previous value of r are no longer required to be dereferenceable or incrementable.

所以在我看来输出必须的分配按顺序进行。它们是否只是意味着 unary_op 的应用程序可能会出现故障,并存储到一个临时位置,但是按顺序复制到输出中?听起来似乎不是您想要做的事情。

So it seems to me that the assignment of the output must happen in order. Do they simply mean that the application of unary_op may be out of order, and stored to a temporary location, but copied to the output in order? That doesn't sound like something you'd ever want to do.

大多数C ++库实际上尚未实现并行执行程序,但Microsoft确实实现了。我很确定是相关代码,并且我认为它调用 populate()函数将迭代器记录到输出的大块中,这肯定是不合法的,因为 LegacyOutputIterator 可以通过增加其副本来使其无效。

Most C++ libraries haven't actually implemented parallel executors yet, but Microsoft has. I'm pretty sure this is the relevant code, and I think it calls this populate() function to record iterators to chunks of the output, which surely isn't a valid thing to do because LegacyOutputIterator can be invalidated by incrementing copies of it.

我缺少了什么?

推荐答案

1)该标准中的输出迭代器要求完全被打破。参见 LWG2035

1) The output iterator requirements in the standard are completely broken. See LWG2035.

2)如果您纯粹使用输出迭代器和纯输入源范围,因此该算法在实践中几乎无能为力。它只能按顺序写。 (但是,假设的实现可以选择特殊情况自己的类型,例如 std :: back_insert_iterator< std :: vector< size_t>> ;我看不到为什么任何实现都希望在这里这样做,但允许这样做。)

2) If you use a purely output iterator and a purely input source range, then there's little else the algorithm can do in practice; it has no choice but to write in order. (However, a hypothetical implementation can choose to special-case its own types, like std::back_insert_iterator<std::vector<size_t>>; I don't see why any implementation would want to do it here, but it is permitted to do so.)

3)标准中没有任何内容可以保证 transform 按顺序应用转换。我们正在查看实现细节。

3) Nothing in the standard guarantees that transform applies the transformations in-order. We are looking at an implementation detail.

std :: transform 仅需要输出迭代器并不意味着它不能检测更高的迭代器强度,并在这种情况下重新排序操作。确实,算法总是在 上调度迭代器强度,并且它们对特殊迭代器类型(例如指针或向量迭代器)始终进行特殊处理。

That std::transform requires only output iterators does not mean it cannot detect higher iterator strengths and reorder the operations in such cases. Indeed, algorithms dispatch on iterator strength all the time, and they have special handling for special iterator types (like pointers or vector iterators) all the time.

当标准要保证特定订单时,它知道如何说(请参阅 std :: copy 的从第一个,然后进行到最后)。

When the standard wants to guarantee a particular order, it knows how to say it (see std::copy's "starting from first and proceeding to last").

这篇关于将std :: transform与std :: back_inserter一起使用是否有效?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆