0

私は(最近)variadicテンプレートについて最近聞いた。コンパイル時間の多項式

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

、単項マイナスとMUL演算子を追加サポートcoudどちら:コンパイル時演算子多項式 - 私はint型を作るための方法があればことを知っているように思います。

[編集]:claryfying質問:

INT-多項式は、基本的に1つの整数のリスト(係数)である。

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

私はこの多項式は、コンパイル時定数で表すことたいです。

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

最初に追加(要素を1つずつ追加する)を考えてみましょう。

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

はそのようなこと何とか演算子+を持つことは可能ですか?

乗算では、同様の(しかし、より複雑な問題です)。

ここに誰かがそれについての経験はありますか?

+1

テンプレートはコンパイル時のメカニズムです。コンパイル時に評価される多項式が必要な場合は、提案しているものを取り除くことができます。実行時の値をテンプレート引数として使用することはできません。多項式の最大次数を単一のテンプレート引数とし、その項を 'std :: array'に格納する方が良いでしょう。 –

+0

'polynom <1,2>'が 'polynom <2,1>'と違う点は何ですか? – HolyBlackCat

+0

@FrançoisAndrieux:係数がコンパイル時定数の場合はどうなりますか? –

答えて

0

正確に何を望んでいるのかわかりませんが(使用例を提案できますか?)、私は方法がstd::integral_constantに基づくタイプのセットを定義していると思います。

を次のように自分の表現をsemplifyするに

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

を次のように

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

と追加演算子を次のように

例では、単項マイナスを定義することができ、あなたは、単一の整数を定義することができます

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); 
}