c++模板来表示多项式



我正在尝试使用模板来表示像x^2+3x+5这样的简单多项式。我的想法是将它们表示为项的和,每个项都有一个系数和一个幂,例如x^2的coeff=1,幂=2。我还希望能够评估一些x的多项式(它们只有1个未知,但在很多地方(。到目前为止,我有:

struct PolyEnd{
double eval(double x){
return 0;
}
};
template <int coeff, int power, class Tail> struct Poly {
typedef Tail tt;
double eval(double x){
double curr = coeff * std::pow(x, power);
return curr; // has to call eval(x) on rest of the terms which are in the tail and return the sum with "curr"
}
};
int main()
{
double x = 2;
Poly<1,1,Poly<1,1,PolyEnd>> poly;
std::cout << poly.eval(x) << std::endl;
return 0;
}

然而,我被卡住了。我所尝试的是可能的吗?如果是这样,我该如何使递归eval((调用工作?

是的,你可以这样做,你只需要在尾部调用eval,由于所有的类都是无状态的,你只需创建一个实例来当场调用成员函数:

struct PolyEnd{
double eval(double x){
return 0;
}
};
template <int coeff, int power, class Tail> struct Poly {
typedef Tail tt;
double eval(double x){
double curr = coeff * std::pow(x, power);
return curr + Tail{}.eval(x);
}
};
int main()
{
double x = 2;
Poly<1,1,Poly<1,1,PolyEnd>> poly;
std::cout << poly.eval(x) << std::endl;
return 0;
}

或者如果您将eval设为static,则可以直接调用Tail::eval(x)

我猜您正在尝试元编程。你的问题也让我很兴奋,因为我也是元编程的新手,我想练习@核桃的答案已经被接受了,但分享另一个实现并没有坏处。我使用了一些基本的元编程技术。

我希望它能帮助你。

#include <cmath>
#include <iostream>
#include <string>
template<int Value>
struct coeff
{   };
template<int Value>
struct power
{   };
template<typename Coefficient, typename Power>
struct term;
template<int Coefficient , int Power>
struct term< coeff<Coefficient> , power<Power> >
{
inline double eval( double  x ) const noexcept { 
return Coefficient * std::pow( x , Power );
}
};
template<int Value>
using constant = term< coeff<Value> , power<1> >;
template<int Value>
using exponential = term< coeff<1> , power<Value> >;
template<typename... T>
struct polynomial
{
static_assert( sizeof...(T) == 0, "A polynomial can only be expressed in 'term's.");
[[nodiscard]] constexpr double eval( double ) const noexcept {
return 0;
}
[[nodiscard]] std::string to_string() const noexcept {
return std::string{};
}
};
template<int Coefficient, int Power, typename... Tail>
struct polynomial<term< coeff<Coefficient> , power<Power> >, Tail...>
:   polynomial<Tail...>
{
[[nodiscard]] constexpr double eval( double x ) const noexcept {
return m_t.eval( x ) + polynomial<Tail...>::eval( x );
}
[[nodiscard]] std::string to_string(){
using namespace std;
using namespace std::string_literals;
return "("s + std::to_string( Coefficient ) + 
string { "x^" } +
std::to_string( Power ) + ( sizeof...(Tail) == 0 ? ")" : ") + " ) + 
polynomial<Tail...>::to_string();
}
private:
term< coeff<Coefficient> , power<Power> > m_t;
};
int main()
{
auto p1 = polynomial<term< coeff<1> , power<2> > ,
term< coeff<2> , power<4> > ,
term< coeff<2> , power<3> > ,
constant<3> ,
exponential<2> >{};
std::cout << "Polynomial is : " << p1.to_string() << std::endl;
std::cout << "f(2) : " << p1.eval( 2 ) << std::endl;
std::cout << "f(3) : " << p1.eval( 3 ) << std::endl;
return 0;
}

在线运行

多项式系数可以存储在std::arraystd::vector中(如果您在运行时定义多项式次数(。

然后用eval函数扩展功能。

template <unsigned N>
class Poly : public std::array<double, N> {
public:
template <typename... E>
Poly(E &&... e) : std::array<double, N>{{std::forward<E>(e)...}} {}
double eval(double x) {
double result = 0;
double exp = 1.;
for (auto it = this->rbegin(); it != this->rend(); ++it) {
result += exp * (*it);
exp *= x;
}
return result;
}
};

使用

double result = Poly<3>{3., 2., 1.}.eval(17);

最新更新