bre*_*ett 1 c++ operator-overloading functor
这段代码有什么问题?这段代码给了我很多语法错误.另外我想知道为什么在C++中使用仿函数.
class f
{
public:
int operator(int a) {return a;}
} obj;
int main()
{
cout << obj(0) << endl;
}
Run Code Online (Sandbox Code Playgroud)
在声明时你错过了一对额外的括号operator().函数的名称是operator(),它仍然需要它之后的参数列表.因此它应该看起来像:
int operator()(int a) {return a;}
Run Code Online (Sandbox Code Playgroud)
像这样的函数对象(aka仿函数)通常用于指向函数的指针.但是,它们的优点是它们可以使用继承并且它们也封装了状态.通常,设计良好的类或函数模板几乎可以与函数指针互换使用它们.但是,当使用模板对象时,优秀的优化器通常可以生成更好的代码.
有关如何使用函数对象的相当复杂的示例,请查看表达式模板.
这是一个关于如何使用继承的一个小的,有点人为的例子:
struct unary_int_func {
virtual int operator()(int i) = 0;
};
struct negate : public unary_int_func {
int operator()(int i) {return -i;}
};
struct one_plus : public unary_int_func {
int operator()(int i) {return i+1;}
};
void show_it(unary_int_func &op, int v) {
cout << op(v) << endl;
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我们创建一个基类,将运算符作为纯虚函数.然后我们推导出实现它的具体类.show_it()然后,代码可以使用从此基础派生的类的任何实例.虽然我们可以使用指向函数的指针来获取int并返回一个int,但这更加类型安全.使用函数指针的代码会接受任何这样的函数指针,这样我们就可以定义一个将int映射到int的全新层次结构:
struct a_different_base_class {
virtual int operator()(int i) = 0;
};
Run Code Online (Sandbox Code Playgroud)
但是这个实例不能与unary_int_func的实例互换.
至于state,考虑一个运行和函数:
struct running_sum : public unary_int_func {
int total;
running_sum() : total(0) {}
int operator()(int i) {return total += i;}
};
int main()
{
running_sum s;
cout << s(1) << endl;
cout << s(2) << endl;
cout << s(3) << endl;
cout << s(4) << endl;
}
Run Code Online (Sandbox Code Playgroud)
这里,running_sum跟踪总数的实例.它将打印出1,3,6和10.指向函数的指针没有这种方式在不同的调用之间保持状态.SGI在函数对象上的STL页面与我的运行总和有一个类似的例子,但展示了如何轻松地将它应用于容器中的一系列元素.