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()中用作左值)
答案 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));