我有一个静态硬编码的测试代码。之后我将其转换为动态绑定来测试性能,虚拟调用似乎慢了大约两倍。
#include <vector>
class vUnit {
public:
virtual ~vUnit() {;}
virtual float process(float f) = 0;
};
class vRack {
public:
vRack() {;}
~vRack() {;}
inline void addUnit(vUnit* unit_ptr) {
_units.push_back(unit_ptr);
}
inline float process_all(float f) {
float res = 0.;
for (int j = 0 ; j< 60; j++) {
for (auto u : _units) {
f = u->process(f);
}
}
res += f;
return res;
}
private:
std::vector<vUnit*> _units ;
int _i = 0;
};
class vMultiplyF : public vUnit {
public:
vMultiplyF(float v) {_f = v;}
inline float process(float f) final {
return f * _f;
}
private:
float _f;
};
class vDivideF : public vUnit {
public:
vDivideF(float v) {_f = v;}
inline float process(float f) final {
if (f > 0) {
return _f / f;
} else return 0.0f;
}
private:
float _f;
};
int main () {
float f = 1.5f, r = 0.0f;
vRack vR;
vMultiplyF vM(5.1f);
vDivideF vD(5.5f);
vR.addUnit(&vM);
vR.addUnit(&vD);
for( int i = 0 ; i < 1000 ; i++) {
f = vR.process_all(f);
r += f;
}
return 0;
}
我认为 CRTP 可能是一个合理的折衷方案,但我不太明白如何重写vRack.addUnit()
以便可以采用不同的 vUnit 实现。有人可以帮忙吗?
15
最佳答案
1
我认为 CRTP 可能是一个合理的折衷方案。
CRTP 在这里帮不了你。你需要一些间接方法来区分不同的操作。
如果配置是静态的,那么您可以从迭代vUnit
s 的容器切换到使用折叠表达式来组合特定对象的元组。
#include <tuple>
template <typename T>
concept Unit = requires(T unit, float f) { f = unit.process(f); };
class vMultiplyF { // No base class needed
public:
vMultiplyF(float v) {_f = v;}
float process(float f) {
return f * _f;
}
private:
float _f;
};
class vDivideF { // No base class needed
public:
vDivideF(float v) {_f = v;}
float process(float f) {
if (f > 0) {
return _f / f;
} else return 0.0f;
}
private:
float _f;
};
template <Unit... Units>
class vRack {
public:
vRack(Units... units) : _units(std::move(units)...) {}
float process_all(float f) {
for (int j = 0 ; j< 60; j++) {
// evaluates (f = unit.process(f)) for each unit in sequence
std::apply([&](Units&... unit){ ((f = unit.process(f)), ...); }, _units);
}
return f;
}
private:
std::tuple<Units...> _units;
};
int main () {
float f = 1.5f, r = 0.0f;
vMultiplyF vM(5.1f);
vDivideF vD(5.5f);
vRack vR(vM, vD); // deduces vRack<vMultiplyF, vDivideF>
for( int i = 0 ; i < 1000 ; i++) {
f = vR.process_all(f);
r += f;
}
return 0;
}
2
-
谢谢,我会用我已有的两个来测试它
– -
vRack
通过添加以下方法可以减少“静态”配置:template <Unit... U> auto add (U...units) { return vRack<Units...,U...> (std::tuple_cat (_units, std::make_tuple (units...))); }
,然后可以通过向现有机架添加一些单元来获得新机架,例如auto vR2 = vR.add (vD);
。但请注意,两个机架不会具有相同的类型。
–
|
float f;
这样做,我会觉得很奇怪vR.process_all(f);
)。–
–
–
–
–
|