我希望基于类中的选项设置几种不同的类实现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:错误:对“(测试)()”
的调用不匹配test.cxx:34:19:错误:无法调用'(Test)()'
答案 0 :(得分:5)
你的类需要以某种方式记住要使用的函数指针。将其存储为类成员:
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;
};
但是,在您努力完成此操作之前,首先分析您的代码并查看通过switch
或if
分支是否实际上是一个瓶颈(它可能不是是!)。现代处理器具有非常违反直觉的性能特征,因此编译器可能能够生成比您想象的更好的代码。确保分支实际上太昂贵而无法使用的唯一方法是分析代码。 (并且通过“剖析”我的意思是“运行设计良好的实验”,而不是“在没有测试的情况下提出预感”。)
答案 1 :(得分:1)
您可以使operator()
内联函数调用另一个指针。优化器应该完全消除额外的间接。
答案 2 :(得分: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