2012-03-06 4 views
0

可変テンプレートを使用してBoost MPLのようなvector_cをどのように書くのだろうと思います。あなたはvectorがそれに少なくとも一つの要素を持たなければならないことに気づくかもしれませんが、それは本当に私のための制限ではありません可変テンプレートを使用したMPLのようなベクター:挿入

template <std::size_t element, std::size_t ... E> 
struct vector 
{ 
    typedef vector<E ...> next; 

    static constexpr std::size_t size() 
    { 
     return sizeof... (E); 
    } 

    static constexpr std::size_t value() 
    { 
     return element; 
    } 
}; 

template <std::size_t element> 
struct vector<element> 
{ 
    // no need to define 'next' here 

    static constexpr std::size_t size() 
    { 
     return 1; 
    } 

    static constexpr std::size_t value() 
    { 
     return element; 
    } 
}; 

:私はすでに次のコードスニペットを書きました。上記の定義によれば、所与のインデックスの要素にアクセスするための「機能」を書くことは非常に容易である:例えば

template <std::size_t index, typename T> 
struct get 
{ 
    typedef typename get<index - 1, typename T::next>::type type; 
}; 

template <typename T> 
struct get<0, T> 
{ 
    typedef T type; 
}; 

は、get<1, vector<1, 2, 3>>正しい結果2を返します。今私の質問:1つは、挿入機能を実装するだろうか? MPLを使用していないのは、insert<>を試したときにvector_cが返されなかったからです。具体的には、挿入は次のように適用されるべきである:

insert<vector<1, 3, 4>, 1, 2>::type 
// ^   ^^ 
//  type   at element 

必須収率vector<1, 2, 3, 4>。それは可能ですか?

答えて

2

insert list 0 element = element : list 
insert list at element = (head list) : insert (tail list) (at-1) element 

とC++のテンプレートにこれを翻訳:あなたは、両方のvector年代のプリミティブpush_frontを定義する必要が

// insert list at element = 
template <typename List, size_t at, size_t element> 
struct Insert 
{ 
    typedef typename 
     // insert (tail list) (at-1) element 
     Insert<typename List::next, at-1, element>::type:: 
     // (head list) : … 
     template push_front<List::value()>::type 
    type; 
}; 

// insert list 0 element = 
template <typename List, size_t element> 
struct Insert<List, 0, element> 
{ 
    // element : list 
    typedef typename List::template push_front<element>::type type; 
}; 

注:

template <std::size_t element, std::size_t ... E> 
struct vector<element, E...> 
{ 
    template <size_t x> 
    struct push_front 
    { 
     typedef vector<x, element, E...> type; 
    }; 
}; 
+0

すてきな解決策 - MPLをどのようにしてバラエティに富んだテンプレートに書き直し/置き換えることができるかの洞察を得るのに役立ちます。 – mark

+0

その間に、私は 'push_front'関数を書く必要があるという結論に達しました - しかし、私はそれがベクトルそのものの中になければならないことを認識しませんでした!私は、ベクトルクラスの外でpush_frontを書くことは不可能だと思います。 – cschwan

+1

@cschwan:もちろん*できます*(例:http://ideone.com/3F4UQ)。私はちょっと気にしないでください。 – kennytm

1

MPLが挿入後にvector_cを返すようにするには、vector_c as_vectorを使用してMPLがそれをcovnertする必要があります。

ここでは半機能的な言語を扱っていますので、挿入したい場合は古いものから新しいvector_cを作り直す必要があります。このような再構築は非常に退屈なので、MPLはベクタ(別名スタティックシーケンスのコンセプトに従います)を返す型を返し、位置Nが必要なときに挿入値を確認するオーバーロードが<>返すものハスケルの面では

+0

説明をありがとう - どこで 'as_vector'を見つけるのですか? – cschwan

関連する問題