代码之家  ›  专栏  ›  技术社区  ›  Luc Touraille

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

  •  10
  • Luc Touraille  · 技术社区  · 17 年前

    我刚读到C++标准 std::for_each find , search 等等这是否意味着应用于每个元素的函数不应修改它们?为什么呢?可能会出什么问题?

    下面是一个示例代码,其中修改了序列。你能看出它有什么毛病吗?

    void foo(int & i)
    {
        i = 12;
    }
    
    int main()
    {
        std::vector<int> v;
        v.push_back(0);
    
        std::for_each(v.begin(), v.end(), foo);
        // v now contains 12
    }
    

    我怀疑这只是一个解释问题,但我想听听你的意见。

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

    4 回复  |  直到 17 年前
        1
  •  21
  •   Community Mohan Dere    9 年前

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

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


    for_each CPL )这是不是说 每人 可以修改序列的元素( http://www.research.att.com/~bs/3rd_printing5.html ):

    “那 for_each() 算法被归类为非修改,因为它不显式地修改序列。但是,如果应用于非常量序列 对于_each() 可能会更改序列的元素。有关示例,请参见的使用 negate() (最近的标准决议)。

    每人 对于_each() 在最终确定之前已删除。

    另见:

        2
  •  16
  •   Johannes Schaub - litb    17 年前

    this defect report

    LWG认为标准中没有禁止修改序列元素的函数对象。问题是,对于_,每个都在一个名为“非置换算法”的段落中,标题可能会令人困惑。非规范性说明应阐明这一点。

    this one .

        3
  •  6
  •   bayda    17 年前

    我认为“非修改序列操作”意味着该操作不会修改 序列 可以修改容器元素

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

        4
  •  2
  •   AJ S.    17 年前

    如上所述,for_被分类为“非置换算法”

    STL的“变异”对应物是std::transform。

    如果我看到std::for_each,很明显,无论foo做什么,它都不会修改容器。

    我遵循的准则可以说是:

    “如果您希望使用容器的元素执行一些不改变元素的任务,请使用std::for_。

    如果您希望使用容器的元素以某种系统方式修改元素,或者在将以某种方式更改元素的任务中使用它们,请使用std::transform。“