当前位置:  开发笔记 > 编程语言 > 正文

为什么std :: for_each是非修改序列操作?

如何解决《为什么std::for_each是非修改序列操作?》经验,为你挑选了3个好方法。

我刚读在C++标准std::for_each是一个非修改序列操作,具有沿find,search等等.这是否意味着应用于每个元素的函数不应该修改它们?这是为什么?什么可能出错?

这是一个示例代码,其中修改了序列.你能看到它有什么问题吗?

void foo(int & i)
{
    i = 12;
}

int main()
{
    std::vector v;
    v.push_back(0);

    std::for_each(v.begin(), v.end(), foo);
    // v now contains 12
}

我怀疑这只是一个解释问题,但我想对此有所了解.

PS:我知道我可以用std::transform而不是for_each,但那不是重点.



1> Michael Burr..:

很简单,您无法进行可以修改容器结构的更改.这是因为在一般情况下,修改容器会使正在使用的迭代器无效.

只要不改变容器的结构(例如容器中元素的顺序),就可以修改元素.

[加成]


请注意,似乎存在一些关于for_each作为"非修改"算法的混淆.Stroustrup在第四版"C++编程语言,第3版"的勘误表中总结了这种令人困惑的情况.(CPL)有关于是否for_each可以修改序列元素的说法(http://www.research.att.com/~bs/3rd_printing5.html):

"该for_each()算法被归类为非修改,因为它没有明确地修改序列.但是,如果应用于非const序列,则for_each()可能会更改序列的元素.例如,请参阅negate()11.9中的使用." (最近的标准解决方案).

CPL最初表示传递给的函数或函数对象for_each不允许修改传递给它的元素.然而,CPL是在标准最终确定之前编写并最初发布的,显然这个限制在for_each()最终确定之前被删除了.

也可以看看:

http://www.angelikalanger.com/Articles/Cuj/03.ForeachTransform/ForEachTransform.html

litb的答案中提到的C++ LWG缺陷报告(http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#475)



2> Johannes Sch..:

请参阅他们所说的缺陷报告

LWG认为标准中没有任何内容禁止修改序列元素的函数对象.问题是for_each是一个名为"非突变算法"的部分,标题可能令人困惑.一份非规范性说明应澄清这一点.

但也要注意这个.

他们似乎称之为"非修改",因为for_each本身并不会明确地修改序列的元素.



3> bayda..:

我认为"非修改序列操作"意味着此操作不会修改序列.但是操作可以修改容器元素.

容器元素和序列的价值 - 不同的东西.

推荐阅读
牛尾巴2010
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有