用std :: for_each改变对象是否可以?

时间:2009-04-04 17:56:27

标签: c++ stl

for_each接受InputIterators:

//from c++ standard
template <class InputIterator, class Function>
   Function for_each (InputIterator first, InputIterator last, Function f);

可以在函数f中更改对象,如下所示:

struct AddOne
{
    void operator()(int & x){x = x + 1;}
};

std::vector<int> vec(10);
std::for_each(vec.begin(),vec.end(),AddOne());

此代码适用于VC ++ 2008以及GCC,但它是否也是可移植(合法)代码? (InputIterators仅保证可用作rvalue,在这种情况下,它们在AddOne的operator()中用作左值)

5 个答案:

答案 0 :(得分:7)

阅读此article

要迂腐:for_each是一个非修改序列操作。目的不是修改序列。但是, 可以在使用for_each时修改输入序列。

答案 1 :(得分:4)

你误会了什么。说输入迭代器只能保证可用,因为rvalues并不意味着你不能以某种方式从迭代器中获取左值。所以这并不意味着*iterator的结果是一个右值。您/ for_each传递给AddOne的内容是operator* - 不是迭代器本身的结果。

关于for_each和修改功能对象 - 阅读this question

答案 2 :(得分:3)

如果有疑问,请使用std :: transform,因为它甚至会向您想要修改内容的代码的随意读者传达。

答案 3 :(得分:2)

这是合法的 - 输入迭代器用于指定范围,而不是进行处理。

有趣的是,Josuttis在他的书“The C ++ Standard Library”中将for_each列为修改,而不是非修改。

答案 4 :(得分:0)

我的建议是,将所有项目传递给函数,即是通过引用还是指针,更改它或作为副本并更改它都很重要。

但正如其他人所说,如果你想改变价值观,最好使用转换,因为它关心的是返回值。

    class MultiplyBy {
    private:
        int factor;

    public:
        MultiplyBy(int x) : factor(x) {
        }

        int operator () (int other) const {
            other = factor + other;
            return other; 
          } 

    //  int operator () (int & other) const { 
    //         other = factor + other;
    //         return other;        
    //     }      
    };

        vector<int> x1= {1, 2, 3, 4, 5};
        vector<int> x2;   
        std::transform(x1.begin(), x1.end(), back_inserter(x2), MultiplyBy(3));
        std::for_each(x1.begin(), x1.end(), MultiplyBy(3));