有两种方法可以创建一个仿函数(一个保持状态的函数):
绑定一个函数并定义一个状态:bind(f, _1, state)
double g(double x,double state){ 返回x +状态; } function f = bind(g,_1,state);
使用()
运算符和类:
struct f {
double state;
f(double state_):state(state_) {}
double operator()(double x) {return x+state;}
};
我发现bind
- 方法写得更快,但我想知道是否有一些隐藏的石头,因为大部分时间在文学中我将functor视为类的()
运算符。
答案 0 :(得分:3)
3. way是lambda表达式:
auto f = [state]( double x ) { return x * state; };
答案 1 :(得分:1)
我认为bind
的灵感来自函数式语言(如标题文件名所示)。
我认为这是相当的,因为它是一个模板函数,但可能通过内置调用优化...
这是我第一次看到这个功能,所以我需要看看asm才能看到差异,然后我会重新发布;)
尽管如此,它不允许您在仿函数中使用其他方法,因此许多用途仍然需要operator()
<强> [编辑] 强> 好的,我看到asm:bind因为模板与“经典方式”相比而增加了很多代码。因此,我建议您使用strucs方法(即只是一个仿函数)。而且,阅读这样的代码更容易理解。 如果你取代参数获利,那么捆绑是好的,但为了简单使用,它是一个激光佳能切割你的奶酪:P 的 [/编辑] 强>
答案 2 :(得分:0)
看起来struct
是更快的方法:
11:01:56 ~/try
> g++ -std=c++11 main.cpp ; ./a.out
in 2265 ms, functor as a struct result = 1.5708e+16
in 31855 ms, functor through bind result = 1.5708e+16
11:02:33 ~/try
> clang++ -std=c++11 main.cpp ; ./a.out
in 3484 ms, functor as a struct result = 1.5708e+16
in 21081 ms, functor through bind result = 1.5708e+16
代码:
#include <iostream>
#include <functional>
#include <chrono>
using namespace std;
using namespace std::placeholders;
using namespace std::chrono;
struct fs {
double s;
fs(double state) : s(state) {}
double operator()(double x) {
return x*s;
}
};
double fb(double x, double state) {
return x*state;
}
int main(int argc, char const *argv[]) {
double state=3.1415926;
const auto stp1 = system_clock::now();
fs fstruct(state);
double sresult;
for(double x=0.0; x< 1.0e8; ++x) {
sresult += fstruct(x);
}
const auto stp2 = high_resolution_clock::now();
const auto sd = duration_cast<milliseconds>(stp2 - stp1);
cout << "in " << sd.count() << " ms, ";
cout << "functor as a struct result = " << sresult << endl;
const auto btp1 = system_clock::now();
auto fbind = bind(fb, _1, state);
double bresult;
for(double x=0.0; x< 1.0e8; ++x) {
bresult += fbind(x);
}
const auto btp2 = high_resolution_clock::now();
const auto bd = duration_cast<milliseconds>(btp2 - btp1);
cout << "in " << bd.count() << " ms, ";
cout << "functor through bind result = " << bresult << endl;
return 0;
}
更新(1)
还可以将函数作为函数对象:
struct fbs {
double operator()(double x, double state) const {
return x*state;
}
};
并在main.cpp中:
const auto bstp1 = system_clock::now();
auto fbindstruct = bind(fbs(), _1, state);
double bsresult;
for(double x=0.0; x< 1.0e8; ++x) {
bsresult += fbindstruct(x);
}
const auto bstp2 = high_resolution_clock::now();
const auto bsd = duration_cast<milliseconds>(bstp2 - bstp1);
cout << "in " << bsd.count() << " ms, ";
cout << "functor through bind-struct result = " << bsresult << endl;
没有改变速度:
> g++ -std=c++11 main.cpp ; ./a.out
hi
in 2178 ms, functor as a struct result = 1.5708e+16
in 31972 ms, functor through bind result = 1.5708e+16
in 32083 ms, functor through bind-struct result = 1.5708e+16
12:15:27 ~/try
> clang++ -std=c++11 main.cpp ; ./a.out
hi
in 3758 ms, functor as a struct result = 1.5708e+16
in 23503 ms, functor through bind result = 1.5708e+16
in 23508 ms, functor through bind-struct result = 1.5708e+16
更新(2)
在相似的时间添加优化结果:
> g++ -std=c++11 -O2 main.cpp ; ./a.out
hi
in 536 ms, functor as a struct result = 1.5708e+16
in 510 ms, functor through bind result = 1.5708e+16
in 472 ms, functor through bind-struct result = 1.5708e+16
12:31:33 ~/try
> clang++ -std=c++11 -O2 main.cpp ; ./a.out
hi
in 388 ms, functor as a struct result = 1.5708e+16
in 419 ms, functor through bind result = 1.5708e+16
in 456 ms, functor through bind-struct result = 3.14159e+16
GCC 4.8.1和Clang 3.3
note Clang 3.3给出了“bind-struct”case
的错误结果<强>更新(3)强>
在Is there a macro-based adapter to make a functor from a class?
进行了更多性能测试