8

我想让一个类operator()根据类中设置的选项实现几种不同的方式。因为这会被调用很多次,所以我不想使用任何分支。理想情况下,这operator()将是一个可以使用方法设置的函数指针。但是,我不确定这实际上会是什么样子。我试过:

#include <iostream>

class Test {
public:
  int (*operator())();

  int DoIt1() {
    return 1;
  }

  int DoIt2() {
    return 2;
  }

  void SetIt(int i) {
    if(i == 1) {
      operator() = &Test::DoIt1;
    } else {
      operator() = &Test::DoIt2;
    }
  }
};

int main()
{
  Test t1;

  t1.SetIt(1);

  std::cout << t1() << std::endl;

  t1.SetIt(2);

  std::cout << t1() << std::endl;

  return 0;
}

我知道如果我创建另一个函数指针并从函数中调用它,它将operator()起作用。但是是否可以让operator()函数本身成为函数指针?类似于我发布的内容(无法编译)?

上面的代码给出:

test.cxx:5:21: 错误: 'operator()' 声明为非函数

test.cxx:在成员函数'void Test::SetIt(int)'中:

test.cxx:17:16: 错误: 'operator()' 未定义

test.cxx:19:16: 错误: 'operator()' 未定义

test.cxx:在函数'int main()'中:

test.cxx:30:19: error: no match for call to '(Test) ()'</p>

test.cxx:34:19: error: no match for call to '(Test) ()'</p>

4

3 回答 3

6

您的班级需要以某种方式记住要使用的函数指针。将其存储为类成员:

class Test
{ 
public:
    Test() : func(0) {}

    int operator()() {
        // Note that pointers to Test member functions need a pointer to Test to work.
        return (this->*func)(); // undefined behavior if func == 0
    }

    void SetIt(int i) { 
        if(i == 1) { 
            func = &Test::DoIt1; 
        } else { 
            func = &Test::DoIt2; 
        } 
    }

private:
    int DoIt1() { 
        return 1; 
    } 

    int DoIt2() { 
        return 2; 
    } 

    // Typedef of a pointer to a class method.
    typedef int (Test::*FuncPtr)(); 
    FuncPtr func; 
};

但是,在您开始执行此操作之前,请先分析您的代码,并查看分支通过switchorif是否实际上是一个瓶颈(它可能不是!)。现代处理器具有非常违反直觉的性能特征,因此编译器可能能够生成比您想象的更好的代码。确保分支实际上对您来说成本太高的唯一方法是分析您的代码。(通过“分析”,我的意思是“运行精心设计的实验”,而不是“在没有测试的情况下提出预感”。)

于 2012-04-20T04:36:14.467 回答
1

您可以使您operator()的内联函数调用另一个指针。优化器应该完全消除额外的间接。

于 2012-04-20T04:36:57.877 回答
1

@In silico 提供了一种解决方案,它在 C++03 和 C++11 中都有效。

这是仅适用于 C++11 的另一种解决方案:

std::function<int(Test*)>  func;

func = &Test::DoIt1; 

func(this); //this syntax is less cumbersome compared to C++03 solution

快速在线完整演示

于 2012-04-20T04:46:19.933 回答