运算符重载问题

时间:2010-09-13 05:31:35

标签: c++ operator-overloading functor

此代码有什么问题?这段代码给了我很多语法错误。另外我想知道为什么在C ++中使用仿函数。

class f
{
public:
    int operator(int a) {return a;}
} obj;

int main()
{
    cout << obj(0) << endl;
}

6 个答案:

答案 0 :(得分:7)

在声明operator()时,您错过了一对额外的括号。函数的名称是operator(),它仍然需要后面的参数列表。因此它应该看起来像:

int operator()(int a) {return a;}

这样的函数对象(a.k.a.仿函数)通常用于指向函数的指针。但是,它们的优点是它们可以使用继承并且它们也封装了状态。通常,设计良好的类或函数模板几乎可以与函数指针互换使用它们。但是,当使用模板对象时,优秀的优化器通常可以生成更好的代码。

有关如何使用函数对象的相当复杂的示例,请查看expression templates.

这是一个关于如何使用继承的一个小的,有点人为的例子:

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

在这种情况下,我们创建一个基类,将运算符作为纯虚函数。然后我们推导出实现它的具体类。然后,show_it()之类的代码可以使用从此基础派生的类的任何实例。虽然我们可以使用指向函数的指针来获取int并返回一个int,但这更加类型安全。使用函数指针的代码将接受任何这样的函数指针,而这样我们就可以定义一个将int映射到int的全新层次结构:

struct a_different_base_class {
    virtual int operator()(int i) = 0;
};

但是这样的实例可以与unary_int_func的实例互换。

对于状态,考虑运行和函数:

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

此处,running_sum的实例会跟踪总数。它将打印出1,3,6和10.指向函数的指针没有这种方式在不同的调用之间保持状态。 SGI在function objects上的STL页面与我的运行总和相似,但展示了如何轻松地将其应用于容器中的一系列元素。

答案 1 :(得分:0)

因为int operator(int)实际上等于int int #something_missing_here#(int)

operator是保留关键字,并且在单独使用时不是限定符作为有效函数标识符/名称。
我会说它用于使编译器理解给定表达式是函数声明尽管使用了无效的标识符(c ++只允许字母和下划线作为命名中的第一个字符)

答案 2 :(得分:0)

Functors基本上是状态函数。它们最大的用途是STL和Boost库。例如,std::sort采用一种名为Comparator的仿函数。在这种情况下,可能已经传递了一个函数对象,但是functor通过您可以拥有的数据成员提供了更大的灵活性,并通过对同一仿函数的后续调用进行操作。函数也用于实现C ++回调。

答案 3 :(得分:0)

由于您已经在运算符重载代码中发现了问题,我宁愿尝试解决您对仿函数的疑问。

Functor是'函数指针'的缩写。 这些被广泛用于提供定制算法行为的句柄,例如STL中的排序算法使用functor作为参数,用户(程序员)可以实现该函数来告诉算法2个元素的比较结果。 / p>

答案 4 :(得分:0)

仿函数是一个对象(类或结构的实例),它通常会重载operator()。仿函数和普通函数之间的区别在于,因为仿函数是一个对象,它可以在调用之间保持状态。

因为仿函数是一个对象,所以继承规则也适用,你可以利用这个优势。

使用STL时,仿函数也很有用。 std :: sort,std :: for_each等允许您处理整个容器的内容(包括数组)。以下是cplusplus.com的一个例子:

// 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;
}

答案 5 :(得分:-3)

试试这个:

class f
{

  public:

   int operator(int a) {return a;}

};

int main()
{
  f obj;
  cout<<obj(0)<<endl;

}