for_each accepts InputIterators :
for_each接受会:
//from c++ standard
template <class InputIterator, class Function>
Function for_each (InputIterator first, InputIterator last, Function f);
is it ok to change the object in Function f, like this :
是否可以改变函数f中的对象,如:
struct AddOne
{
void operator()(int & x){x = x + 1;}
};
std::vector<int> vec(10);
std::for_each(vec.begin(),vec.end(),AddOne());
This code works in VC++2008 and also with GCC, but is it also portable (legal) code ?
(InputIterators are only guaranteed to be usable as rvalue, in this case they are used as lvalue in AddOne's operator())
这段代码可以在vc++ 2008和GCC中使用,但是它也是可移植的(合法的)代码吗?(InputIterators只保证作为rvalue可用,在本例中,它们在AddOne的操作符()中用作lvalue)。
5 个解决方案
#1
7
Read this article.
读这篇文章。
To be pedantic: for_each
is a non-modifying sequence operation. The intent is not to modify the sequence. However, it is okay to modify the input sequence when using for_each
.
pedantic: for_each是一个不修改的序列操作。目的不是要修改序列。但是,在使用for_each时可以修改输入序列。
#2
4
You misunderstand something. Saying input iterators are only guaranteed to be usable as rvalues doesn't mean you can't get an lvalue out of an iterator somehow. So it does not mean that the result of *iterator
is an rvalue. What you/for_each passes to AddOne
is the result of operator*
- not the iterator itself.
你误解了什么。输入迭代器只能保证作为rvalues使用,但这并不意味着不能从迭代器中获得lvalue。所以这不意味着*iterator的结果是一个rvalue。您/for_each传递给AddOne的是操作符*的结果——而不是迭代器本身。
About for_each
and a modifying function object - read this question
关于for_each和一个修改函数对象——读这个问题。
#3
3
If in doubt use std::transform as it will convey even to the casual reader of your code that you intend to modify something.
如果有疑问使用std::转换,因为它将传递到您的代码的临时读者,您打算修改一些东西。
#4
2
It is legal - the input iterators are used to specify the range, not to do the processing.
这是合法的——输入迭代器用于指定范围,而不是进行处理。
Interestingly, Josuttis in his book "The C++ Standard Library" lists for_each
as modifying, raher than non-modifying.
有趣的是,Josuttis在他的书“c++标准库”中列出了for_each作为修改,而不是不修改。
#5
0
My suggestion would be, it all matters how you pass your item to the function i.e. whether by reference or pointer and change it or as a copy and change it.
我的建议是,你如何将你的项目传递给函数,例如,通过引用或指针修改它,或者作为一个拷贝修改它。
But as other's have said, if you want to change the values, it's better to use transform as it cares about the return values.
但正如其他人所说,如果您想要更改值,最好使用转换,因为它关心返回值。
class MultiplyBy {
private:
int factor;
public:
MultiplyBy(int x) : factor(x) {
}
int operator () (int other) const { // what if you pass by ref
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));
#1
7
Read this article.
读这篇文章。
To be pedantic: for_each
is a non-modifying sequence operation. The intent is not to modify the sequence. However, it is okay to modify the input sequence when using for_each
.
pedantic: for_each是一个不修改的序列操作。目的不是要修改序列。但是,在使用for_each时可以修改输入序列。
#2
4
You misunderstand something. Saying input iterators are only guaranteed to be usable as rvalues doesn't mean you can't get an lvalue out of an iterator somehow. So it does not mean that the result of *iterator
is an rvalue. What you/for_each passes to AddOne
is the result of operator*
- not the iterator itself.
你误解了什么。输入迭代器只能保证作为rvalues使用,但这并不意味着不能从迭代器中获得lvalue。所以这不意味着*iterator的结果是一个rvalue。您/for_each传递给AddOne的是操作符*的结果——而不是迭代器本身。
About for_each
and a modifying function object - read this question
关于for_each和一个修改函数对象——读这个问题。
#3
3
If in doubt use std::transform as it will convey even to the casual reader of your code that you intend to modify something.
如果有疑问使用std::转换,因为它将传递到您的代码的临时读者,您打算修改一些东西。
#4
2
It is legal - the input iterators are used to specify the range, not to do the processing.
这是合法的——输入迭代器用于指定范围,而不是进行处理。
Interestingly, Josuttis in his book "The C++ Standard Library" lists for_each
as modifying, raher than non-modifying.
有趣的是,Josuttis在他的书“c++标准库”中列出了for_each作为修改,而不是不修改。
#5
0
My suggestion would be, it all matters how you pass your item to the function i.e. whether by reference or pointer and change it or as a copy and change it.
我的建议是,你如何将你的项目传递给函数,例如,通过引用或指针修改它,或者作为一个拷贝修改它。
But as other's have said, if you want to change the values, it's better to use transform as it cares about the return values.
但正如其他人所说,如果您想要更改值,最好使用转换,因为它关心返回值。
class MultiplyBy {
private:
int factor;
public:
MultiplyBy(int x) : factor(x) {
}
int operator () (int other) const { // what if you pass by ref
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));