我对向量中的for_each有疑问,代码如下:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
struct myclass {
void operator() (int i) {cout << " " << i;}
} myobject;
int main () {
vector<int> myvector(3,4);
cout << "\nmyvector contains:";
for_each (myvector.begin(), myvector.end(), myobject);
cout << endl;
return 0;
}
for_each()的第三个参数应该是函数名吗? 如果我们传递结构的名称,这是如何工作的?
答案 0 :(得分:8)
这是functor。
std::for_each
是一个功能模板,基本上扩展为:
for (iter = myvector.begin(); iter != myvector.end(); ++iter)
{
myobject(*iter);
}
因此myobject
可以是函数指针,也可以是operator()
重载的对象。
答案 1 :(得分:2)
for_each
的第三个参数可以是像函数那样的任何内容,即可以像x()
一样调用它。由于你的struct重载operator()
,它恰恰就是这种行为。
重载()-operator的类称为“functor”或“function objects”。它们的强大之处在于,您可以在类成员中存储其他数据(例如累加器或初始值),同时仍然表现得像普通函数。
答案 2 :(得分:2)
不一定。 for_each
期望一个可以像函数一样被调用的对象(仿函数)。换句话说,一个重载operator()(T)
的对象,其中T是应用for_each
的容器中保存的值的类型。
答案 3 :(得分:1)
您没有传递类型或(引用)“结构名称”,而是传递对象。语法
struct Foo {
} foo;
实际上声明了Foo
类型和foo
类型的对象Foo
。
首选传递函数对象而不是函数指针。也可以看看 this关于原因。
答案 4 :(得分:0)
由于您为operator () (int)
重载myclass
,因此函数名称将从结构本身解析。有关详细信息,请参阅for_each
。
答案 5 :(得分:0)
它不是函数名,它是一个函数对象(仿函数)。
您可以通过定义具有合适operator()
实现的类来自行手动执行此操作,也可以使用Boost.Function或类似功能将函数包装为仿函数。
请注意,这里有一个微妙的问题。如果您在此处定义operator()
,则代码可以正常工作,但不能用于更新矢量元素。如果您希望更新到位,则需要将其定义为(例如):
void operator() (int& i) { i *= 2; }
更常见的是如何定义仿函数 - 参数通过引用而不是值传递。
答案 6 :(得分:0)
代码很好地解释了,我认为你找到了它:
网站上的示例如下所示:
// for_each example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
void myfunction (int i) {
cout << " " << i;
}
struct myclass {
void operator() (int i) {cout << " " << i;}
} myobject;
int main () {
vector<int> myvector;
myvector.push_back(10);
myvector.push_back(20);
myvector.push_back(30);
cout << "myvector contains:";
for_each (myvector.begin(), myvector.end(), myfunction);
// or:
cout << "\nmyvector contains:";
for_each (myvector.begin(), myvector.end(), myobject);
cout << endl;
return 0;
}