[英]How to create an array to hold C++ classes (not instances) to be used iteratively in a template function
[英]How to hold values used to calculations in c++ template class?
您好,我怀疑在 c++ 模板 class 中保留用于计算的值。
场景如下,我们有很多函数在计算中使用一些嵌套计算来设置一些状态/值等。这些嵌套计算对于所有这些函数都是重复的。
问题是在模板的情况下哪种方法是正确的? 将这些值保留为成员值? 或者只是调用内联 function 它将执行就地计算? 可以说该成员函数/值的值是根据模板参数及其大小计算的,并且有一些数学运算,例如乘法,减法和除法,通常说我们不想重复的困难数学公式。
具有成员值的方法:
template <typename T>
class ApproachWithMemberValue {
public:
void firstOperation()
{
member_ = (member_ / importantValueUsedMultipleTime_) + something;
}
void secondOperation()
{
member_ = (1 / (member_ / importantValueUsedMultipleTime_)) * something;
}
//And other plenty of functions which uses importantValueUsedMultipleTime_
private:
T val_;
size_t member_;
constexpr size_t importantValueUsedMultipleTime_ = resultOfOperations;
//Some mathematical computations based on type of val_ and its value but calculated directly in importantValueUsedMultipleTime_
};
与成员 function 的方法:
template <typename T>
class ApproachWithMemberFunction {
public:
void firstOperation()
{
member_ = (member_ / getImportantValueUsedMultipleTime()) + something;
}
void secondOperation()
{
member_ = (1 / (member_ / getImportantValueUsedMultipleTime())) * something;
}
//And other plenty of functions which uses getImportantValueUsedMultipleTime()
private:
T val_;
size_t member_;
constexpr inline size_t getImportantValueUsedMultipleTime()
{
//Some mathematical computations based on type of val_ and its value
return resultOfOperation;
}
};
哪种方法在计算效率和代码质量方面更好? 调用 function getImportantValueUsedMultipleTime() 会返回计算值还是将计算放在使用它的地方?
要回答您提出的问题,似乎在没有优化的情况下,直接调用constexpr
function 而不将其存储在static constexpr
成员中的版本可以生成更多代码。 这种差异可能会通过优化 go 消失,但如果你想更加确定你可以声明 function consteval
。 查看每个版本的生成代码: https://godbolt.org/z/46xeebbcn
现在,希望能回答你想问的问题。 您需要使用某些东西初始化static constexpr
成员,在您的情况下,大概是可以在编译时评估的constexpr
function ,称之为getImporantValueUsedMultipleTimes()
。 如果此函数取决于“ val_
的类型及其值”,则无法在编译时对其进行评估,因为val_
是运行时变量。
您可能正在寻找的解决方案是某种类型的记忆。 如果您真的希望在编译时完成计算,那么可能是这样的: https://godbolt.org/z/o7cqzjjbW
template<typename T>
consteval T computeValue(T arg) {
return arg * 2;
};
template<typename T>
struct MemoizedValues {
static inline const std::unordered_map<T, T> k_Values{
{0, computeValue(0)},
{1, computeValue(1)}};
};
template<typename T>
T getPrecomputedValue(T arg) {
return MemoizedValues<T>::k_Values.at(arg);
};
template<typename T>
struct UsingMemoizedValues
{
T foo() {
return getPrecomputedValue(m_val);
}
T m_val;
};
int main() {
UsingMemoizedValues<int>{}.foo();
}
但这要求您在编译时知道在运行时可能获得的所有可能的参数值(在示例中仅支持 0 和 1),这是一个很高的要求。 您更有可能需要一个系统,该系统在运行时缓存constexpr
(注意,不是consteval
) computeValue()
的结果,并在第二次询问时返回该结果。 如果您知道有一些常用的值,您可以使用这些值的结果初始化缓存,只要您使用文字或constexpr
arguments,那么应该在编译时评估computeValue()
。
当然,有一些开源库可以为您执行此操作,例如https://github.com/jimporter/memo 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.