【发布时间】:2021-03-30 10:17:54
【问题描述】:
我正在努力改进我的 C++ 编码,我想问一下以下问题的最有效和最优雅的解决方案是什么:
我实现了一个有两个成员函数的类。他们都填充了一个双打数组。这些函数的主体是相同的,只是内部有一个调用。在其中之一中,我想调用幂函数pow(x[idx], Moment)。另一方面,我想调用另一个类的另一个对象的另一个成员函数。
#include <vector>
#include <cmath>
class Pot {
public:
Pot() {}
virtual double GetPot(const double x) const {return sin(x);}
virtual ~Pot() {}
}
class BSplOper {
private:
const Pot *m_p;
... (other private members)
public:
BSplOper(const Pot *p) : m_p{p} {}
virtual ~BSplOper() {}
void MkMat1();
void MkMat2();
}
void BSplOper::MkMat1() {
double val = 0.0;
for (some nested loops here) {
... (some more code - index transformations, etc)
for (int indx = 0; indx < LargeNumber; indx++) {
... (some more nested loops)
val += pow(x[indx], someconst);
}
}
}
void BSplOper::MkMat2() {
double val = 0.0;
for (the same code as in MkMat1) {
...(the same code as in MkMat1)
for (int indx = 0; indx < LargeNumber; indx++) {
... (the same code as MkMat1)
val += m_p->GetPot(x[indx]);
}
}
}
有没有办法将它实现为单个函数,该函数将有一个参数来决定将在内部调用哪个函数?问题是这个函数会被调用很多次,它的性能真的很重要。它位于一系列嵌套循环中。因此,我不想在里面放一个条件。
我正在考虑使用std::function 作为这个成员函数的参数,它将引用传递给预期的函数。但是,我不确定std::function 的开销。
使用模板化成员函数会更有效吗?类似的东西
template<typename F>
void BSplOper::MkMat(F fnx) {
double val = 0.0;
for (the same code as in MkMat1) {
...(the same code as in MkMat1)
for (int indx = 0; indx < LargeNumber; indx++) {
... (the same code as MkMat1)
val += (*fnx)(x[indx]);
}
}
}
在这种情况下,调用它的正确语法是什么?还是这两种解决方案都完全错误?感谢您的任何建议。
【问题讨论】:
-
如果只有两种可能,你可以使用一个名为 pw 的布尔值,例如:
val += pw? pow(x[indx],someconst) : m_p->GetPot(x[indx]); -
感谢您的回复。我认为最好避免嵌套循环内部的条件。在过去,我已经看到这种事情对类似应用程序的性能产生了相当大的负面影响。那我觉得最好有两个独立的函数。
-
您可以使用带有此布尔值的模板。在这种情况下,编译器将在嵌套循环中创建两个没有测试的函数
-
@TUIlover:正式来说会有一个测试,你需要遵守C++语法规则进行测试。但实际上,每个体面的优化器都会发现这一点并消除测试。
-
@MSalters 是的,我的意思是,我没有说清楚
标签: c++ templates function-pointers