gpt4 book ai didi

C++数组作为模板参数

转载 作者:行者123 更新时间:2023-11-28 05:46:44 28 4
gpt4 key购买 nike

我想编写一个简单的多项式类,它可以接受一个系数数组并在编译时将其展开为一个函数,这样我就不需要在运行时遍历这些系数。我想做这样的事情:

template <PARAM_TYPE, PARAMS>
class P {
public:
PARAM_TYPE eval(PARAM_TYPE p){
//Does PARAMS[0] * pow(p, PARAMS.length() -1) + ... + PARAMS[N-1]
}
}

调用示例

P<double,{2,4,3}> quadratic;
quadratic.eval(5); //returns 73

我不想做循环,因为那会花费时间。理想情况下,我希望能够在编译时形成上面的表达式。这可能吗?谢谢

最佳答案

这是一个做你想做的事的例子。编译器对是否将所有代码优化为常量很挑剔,这取决于我注意到的用法和您使用的编译器。

test here

#include <type_traits>

template<class T, unsigned Exponent>
inline constexpr typename std::enable_if<Exponent == 0, T>::type
pow2(const T base)
{
return 1;
}

template<class T, unsigned Exponent>
inline constexpr typename std::enable_if<Exponent % 2 != 0, T>::type
pow2(const T base)
{
return base * pow2<T, (Exponent-1)/2>(base) * pow2<T, (Exponent-1)/2>(base);
}

template<class T, unsigned Exponent>
inline constexpr typename std::enable_if<Exponent != 0 && Exponent % 2 == 0, T>::type
pow2(const T base)
{
return pow2<T, Exponent / 2>(base) * pow2<T, Exponent / 2>(base);
}

template<typename ParamType>
inline constexpr ParamType polynomial(const ParamType&, const ParamType& c0)
{
return c0;
}

template<typename ParamType, typename Coeff0, typename ...Coeffs>
inline constexpr ParamType polynomial(const ParamType& x, const Coeff0& c0, const Coeffs& ...cs)
{
return (static_cast<ParamType>(c0) * pow2<ParamType, sizeof...(cs)>(x)) + polynomial(x, static_cast<ParamType>(cs)...);
}

unsigned run(unsigned x)
{
return polynomial(x, 2, 4, 3);
}

double run(double x)
{
return polynomial(x, 2, 4, 3);
}

unsigned const_unsigned()
{
static const unsigned value = polynomial(5, 2, 4, 3);
return value;
}

double const_double()
{
static const double value = polynomial(5, 2, 4, 3);
return value;
}

编辑:我已将代码更新为使用 pow2<>() 的调整版本在编译时主动执行计算。此版本在 -O2 处优化得非常好它实际上让我感到惊讶。您可以使用代码上方的按钮查看为完整程序生成的程序集。如果所有参数都是常量,编译器将在编译时生成整个常量值。如果第一个参数依赖于运行时,它仍然会为它生成非常紧凑的代码。

(感谢 this question 上的@dyp 为 pow 提供灵感)

关于C++数组作为模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36073341/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com