我有一个很长的算法应该处理从多个#define
描述的一些指令,以便大大减少我的源代码。例如:
#define LongFunction(x, y, alg) return alg(x, y)
#define Alg1(x, y) ((x)+(y))
#define Alg2(x, y) ((x)^((x)-(y)))
我需要做的就是
LongFunction(x, y, Alg1);
LongFunction(x, y, Alg2);
我不想将函数作为参数传递,因为LongFunction
充满了循环,我希望代码尽可能快。我怎样才能巧妙地完成这项任务?
答案 0 :(得分:3)
有很多方法可以参数化函数。
使用宏看起来很简单,但宏不考虑范围,参数替换和副作用存在问题,所以它们是Evil™。
在C ++ 11及更高版本中,最自然的选择是使用std::function
和lambdas,如下所示:
#include <functional> // std::function
#include <math.h> // pow
using std::function;
auto long_function(
double const x,
double const y,
function<auto(double, double) -> double> alg
)
-> double
{
// Whatever.
return alg( x, y ); // Combined with earlier results.
}
auto alg1(double const x, double const y)
-> double
{ return x + y; }
auto alg2(double const x, double const y)
-> double
{ return pow( x, x - y ); }
#include <iostream>
using namespace std;
auto main() -> int
{
cout << long_function( 3, 5, alg1 ) << endl;
}
关于“尽可能快”,使用现代编译器,宏代码可能不会更快。但由于这很重要,请衡量。对于版本构建和典型执行环境,只有测量可以告诉您什么是最快的以及速度是否与最终用户相关。
旧的,并且正式地,您可以使用inline
说明符来向编译器提示它应该对函数进行内联调用。现代编译器可能只是忽略了inline
(它有另一个更有保障的含义,即ODR)。但是应用它可能不会有害。同样,衡量也很重要。请注意,结果可能因编译器而异。
上面的一个替代方法是传递一个简单的函数指针。这可能比std::function
更快,但不太通用。但是,在另一个方向上,您可以使用成员函数对类型进行模板化,这样可以为编译器提供更多信息,更多内联机会,代价是无法以在运行时从数组中选择操作。我相信,当你测量时,如果这很重要,你会发现模板化产生最快的代码。或者至少和上面一样快。
提供操作的类型上的模板化示例:
#include <math.h> // pow
template< class Op >
auto long_function( double const x, double const y )
-> double
{
// Whatever.
return Op()( x, y ); // Combined with earlier results.
}
struct Alg1
{
auto operator()(double const x, double const y)
-> double
{ return x + y; }
};
struct Alg2
{
auto operator()(double const x, double const y)
-> double
{ return pow( x, x - y ); }
};
#include <iostream>
using namespace std;
auto main() -> int
{
cout << long_function<Alg1>( 3, 5 ) << endl;
}
顺便提一下,请注意 ^
不是C ++中的取幂运算符(它在例如Visual Basic中)。在C和C ++中,它是一个小级的XOR运算符。在上面的代码中,我假设你真的是指取幂,并使用pow
中的<math.h>
函数。
相反,如果你真的意味着等级XOR,那么参数需要是整数(最好是无符号整数),这表示你需要long_function
的参数类型,具体取决于指定的参数类型操作。这是一个棘手的问题,但涉及过载或模板,或两者兼而有之。如果那是你真正想要的,那么请详细说明。