【问题标题】:Is it ok to mutate objects with std::for_each?可以用 std::for_each 改变对象吗?
【发布时间】:2009-04-04 17:56:27
【问题描述】:

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 只保证可用作右值,在这种情况下,它们在 AddOne 的 operator() 中用作左值)

【问题讨论】:

    标签: c++ stl


    【解决方案1】:

    阅读此article

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

    【讨论】:

      【解决方案2】:

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

      关于for_each 和一个修改函数对象——阅读this question

      【讨论】:

        【解决方案3】:

        如果有疑问,请使用 std::transform,因为它甚至会向您的代码的普通读者传达您打算修改某些内容。

        【讨论】:

          【解决方案4】:

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

          有趣的是,Josuttis 在他的《C++ 标准库》一书中将 for_each 列为修改,而不是非修改。

          【讨论】:

            【解决方案5】:

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

            但正如其他人所说,如果您想更改值,最好使用转换,因为它关心返回值。

                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));  
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-09-09
              • 2021-08-05
              • 1970-01-01
              • 2011-01-07
              相关资源
              最近更新 更多