假设我有以下要重构的代码:
int toFuture()
{
precalc();
int calc = 5 * foobar_x() + 3;
postcalc();
return calc;
}
int toPast()
{
precalc();
int calc = 5 * foobar_y() - 9;
postcalc();
return calc;
}
在classic-C中,我将这个代码重构为一个worker(),它接受一个执行计算的函数指针:worker()中的公共代码,函数指针提供的特定代码。
使用C ++ 11,我应该使用lambda吗?如果是这样,在这种情况下我将如何实现它?
编辑:我突然意识到模板也可以运作。模板实现如何与其他两个进行比较?
答案 0 :(得分:40)
一种方法:
template<typename CalcFuncT>
int perform_calc(CalcFuncT&& calcfunc)
{
precalc();
int const calc = std::forward<CalcFuncT>(calcfunc)();
postcalc();
return calc;
}
int main()
{
perform_calc([]{ return 5 * foobar_x() + 3; }); // toFuture
perform_calc([]{ return 5 * foobar_y() - 9; }); // toPast
}
答案 1 :(得分:22)
如果您想要使用C ++ 11功能的模板方法,可能看起来很简单:
template<typename FuncType>
auto calculation(FuncType&& func) -> decltype(func())
{
precalc();
auto ret = func();
postcalc();
return ret;
}
然后,您只需调用calculation
函数并将其传递给lambda,functor或函数指针。在这种情况下,你唯一的困难就是如果你传递了一个void
返回类型的函数......在这种情况下你会得到一个编译器错误(这对运行时错误是一件好事)
答案 2 :(得分:7)
我说你是从错误的方面重构:
struct CalcGuard {
CalcGuard() { /* replaces precalc() */ }
~CalcGuard() { /* replaces postcalc() */ }
};
int toFuture()
{
return CalcGuard(), calc = 5 * foobar_x() + 3;
}
int toPast()
{
return CalcGuard(), calc = 5 * foobar_y() - 9;
}
答案 3 :(得分:1)
有一种C/C++
方式可以执行此操作,并采用C++11
方式。这两种方式都不涉及lambdas或模板。
C/C++
方式:
double MyFunc (int x, float y) { return x + y ; }
int main()
{
double (*pf) (int, float) ;
pf = MyFunc ;
pf (101, 202.0) ;
}
C++11
方式:
#include <functional>
double MyFunc (int x, float y) { return x + y ; }
int main()
{
std::function<double (int, float)> f ;
f = MyFunc ;
f (51, 52.0) ;
}
在任何一种情况下,您只需将pf
或f
作为参数传递给重构函数即可。使用lambdas或模板在这里是过度的。