我有以下问题。我编写了以下方法。设置标志后,使用哪个版本。
#define version2
void calc(double &x
#ifdef version2
, double &dot_x
#endif){
for(int i=0;i<n;i++){
double data[]=[... expensive computation ...];
x=[... something depending on data...];
#ifdef version2
dot_x=[... something depending on data ...];
#endif
}
}
但是现在,我需要同时使用这两个版本而且我不想复制它。因为每次都必须对两个版本中的数据进行更改。 是否有可能(如makro等)在一个地方实现两个版本?没有if-decitions,这会耗费时间吗?
非常感谢您的回答,
kildschrote
答案 0 :(得分:2)
只需定义函数的2个重载,一个带一个参数,一个带2:
void calc(double &x){...}
void calc(double &x, double &dot_x){...}
并将公共代码分解出来。然后,您可以(在运行时或在编译时,通过#ifdef
)决定要调用哪个重载。
您甚至可以只定义一个版本,使用默认的第二个参数(指针类型),
void calc(double &x, double *dot_x = nullptr){...}
如果没有明确指定第二个参数(即保留nullptr
),那么执行“便宜”计算,如果没有,则执行“昂贵”计算。
我会尽可能地避免宏(除非真的有必要),因为它们会降低你的代码的可读性并导致令人讨厌的副作用。
答案 1 :(得分:0)
您可以使用模板来编写&#39;两个版本的函数:
template<typename FUNCTOR>
void calc_impl(double &x, FUNCTOR f){
for(int i=0; i<n; i++){
double data[] = [... expensive computation ...];
x = [... something depending on data...];
f(data);
}
}
namespace NULL_F{
struct F{
void operator(double data[]){}
};
}
namespace OPERATE_F{
struct F{
F(double &d_x): dot_x(d_x) {}
void operator(double data[]) {
dot_x = [... something depending on data ...];
}
double &dot_x;
};
}
void calc(double &x){
calc_impl(x, NULL_F::F());
}
void calc(double &x, double &dot_x){
calc_impl(x, OPERATE_F::F(dot_x));
}
模板函数calc_impl
等同于包含所有内容的函数。
calc
的两个重载选择运行哪个版本,使用两个仿函数中的一个来做任何事情或使用dot_x
写入double data[]
。