0

我(最后)最近听说可变参数模板。我想知道,如果有一种方法可以让一个INT - 多项式编译时间运营商:编译时间polynoms

template <int... coefs> 
struct polynom {} 

哪些coud支持加,一元减号和MUL操作符。

[编辑]:claryfying问题:

甲INT-多项式是基本上一个整数列表(系数):

1 + 2x^2 - 7x^5 <=> (1, 0, 2, 0, 0, -7) 

我想这个多项式由一个编译时间常数来表示:

polynom<1,0,2,0,0,-7> 

让我们先考虑加法(在其中我们逐个添加元素)。

是否有可能总得有一个运营商+这样的:

polynom<1,0,1> + polynom<-1,2,1,3> -> polynom<0, 2, 2, 3> 

对于乘法,它将是一个类似的(但更复杂的问题)。

有人在这里有任何经验吗?

+1

模板是一种编译时机制。如果你想要一个在编译时评估的多项式,你可以避开你提出的问题。无法将运行时值用作模板参数。你最好只是把你的polynom作为单个模板参数的最大程度并将这些项存储在一个'std :: array'中。 –

+0

“polynom <1,2>”与“polynom <2,1>”有什么不同? – HolyBlackCat

+0

@FrançoisAndrieux:如果我的系数是编译时间常量? –

回答

0

我不明白你到底想要什么(你能提出一个使用的例子吗?),但我想一种方法是根据std::integral_constant定义一组类型。

例如,一元减可以如下

template <typename T> 
struct uminus 
    : std::integral_constant<typename T::value_type, - T::value> 
{ }; 

和附加操作如下

template <typename T1, typename T2> 
struct add 
    : std::integral_constant<typename T1::value_type, T1::value + T2::value> 
{ }; 

要semplify您的表达式定义,你可以按照如下

定义一个整数
template <int I> 
struct i : std::integral_constant<int, I> 
{ }; 

所以你可以写下如下表达式(计算编译时间)

constexpr auto val = add<i<5>, uminus<i<3>>>::value; 

下面是一个完整的工作示例

#include <iostream> 
#include <type_traits> 

template <typename T> 
struct uminus 
    : std::integral_constant<typename T::value_type, - T::value> 
{ }; 

template <typename T1, typename T2> 
struct add 
    : std::integral_constant<typename T1::value_type, T1::value + T2::value> 
{ }; 

template <int I> 
struct i : std::integral_constant<int, I> 
{ }; 

int main() 
{ 
    constexpr auto val = add<i<5>, uminus<i<3>>>::value; 

    std::cout << val << std::endl; // print 2 
} 
2

这是我在10分钟内,可能不是最优雅的或有效的解决办法,但很简单一个想到了,只使用无聊的沼泽标准通过可变参数列表递归的技术。

#include <iostream> 

// our polynomials are little-endian: the first coefficient is for power 0, 
// the second one is for power 1 etc 
// The empty list corresponds to the zero polynomial 
template <int ... coeff> struct Poly {}; 

// Print it out 
template <int ... coeff> std::ostream& operator<< (std::ostream& os, Poly<coeff...>); 
template <> std::ostream& operator<< (std::ostream& os, Poly<>) { return os; } 
template <int coeff0, int ... coeff> std::ostream& operator<< (std::ostream& os, Poly<coeff0, coeff...>) { 
    os << coeff0 << " " << Poly<coeff...>(); 
} 

// For number coeff0 and polynomial poly(x), return coeff0 + x * poly(x) 
template <int coeff0, class poly> struct poly_shift; 
template <int coeff0, int ... coeff> struct poly_shift<coeff0, Poly<coeff...>>{ 
    using type = Poly<coeff0, coeff...>; 
}; 

// Addition of polynomials 
template <class poly1, class poly2> 
struct poly_add; 
template <> 
struct poly_add<Poly<>, Poly<>> { using type = Poly<>; }; 
template <int ... coeff> 
struct poly_add<Poly<coeff...>, Poly<>> { using type = Poly<coeff...>; }; 
template <int ... coeff> 
struct poly_add<Poly<>, Poly<coeff...>> { using type = Poly<coeff...>; }; 
template <int coeff_l0, int coeff_r0, int... coeff_l, int... coeff_r> 
struct poly_add<Poly<coeff_l0, coeff_l...>, Poly<coeff_r0, coeff_r...>> { 
    using type = typename poly_shift<coeff_l0 + coeff_r0, typename poly_add<Poly<coeff_l...>, Poly<coeff_r...>>::type>::type; 
}; 

// convenient infix operator for values 
template <class poly1, class poly2> 
constexpr typename poly_add<poly1, poly2>::type operator+ (poly1 p1, poly2 p2) { return {}; } 

// test it 
int main() 
{ 
    Poly <1,2,3> a; 
    Poly <3,4,5,6> b; 
    std::cout << (a+b); 
}