2013-12-20 6 views
6

は、私は次のクラス定義を持っていると仮定します。(同じタイプの)指定された数の要素でboost :: tupleを作成するにはどうすればよいですか?

template <unsigned int N> 
class foo 
{ 
    boost::tuples::tuple<...> bar; 
}; 

Nコンパイル時の定数を考えると、私は指定されたタイプのN要素を保持しているタプルであることをbarの種類を拡大したいと思います。つまり、foo<2>::barのタイプはboost::tuples::tuple<T, T>となります。私はこれにBoost.MPLを使用することができると推測していますが、正確なシーケンスはまだわかりません。私は何ができると思う:

template <typename T, int N> 
struct type_repeater 
{ 
    typedef typename boost::mpl::fold< 
     boost::mpl::range_c<T, 0, N>, 
     boost::mpl::vector<>, 
     boost::mpl::push_back<_1, T> 
    >::type type; 
}; 

だからそのインスタンス type_repeater<T, 2>::typeため boost::mpl::vector<T, T>に相当します。私はそのタイプのリストを取り、それをタプルの引数リストに挿入することができるかどうかはわかりません。これは可能ですか?

+0

C++ 11にアクセスできない場合は、これを高める必要はありません。代わりにC++ 11を使用するバージョンでOKでしょうか? – OmnipotentEntity

+0

いずれのケースでも最高の解決策を聞いていますが、結局は少なくともC++ 03の実装が必要になります。 –

答えて

3

を使用すると、あなたは私が考えて欲しいもののために最善の解決策は、単にstd::arrayを使用することです。 N個のインスタンスのTを持つコンテナが必要な場合は、std::arrayの署名はすでにtemplate <typename T, std::size_t N> class arrayです。私はそれが正確にあなたのニーズに合っていると思います。あなたがC++ 11にアクセスすることはできませんが、アクセス権を持っていない場合:

#include <tuple> 

/* Forward declaration. */ 
template <std::size_t N, typename T> 
class Tuple; 

/* Convenience type alias. */ 
template <std::size_t N, typename T> 
using TTuple = typename Tuple<N, T>::type; 

/* Base case. */ 
template <typename T> 
class Tuple<0, T> { 
    public: 

    using type = std::tuple<>; 

}; // Tuple<0> 

/* Recursive case. */ 
template <std::size_t N, typename T> 
class Tuple { 
    public: 

    /* Note the use of std::declval<> here. */ 
    using type = decltype(std::tuple_cat(std::declval<std::tuple<T>>(), 
             std::declval<TTuple<N - 1, T>>())); 

}; // Tuple<N, T> 

/* std::declval<> is necessary to support non default constructable classes. */ 
class NoDefault { 
    public: 

    NoDefault() = delete; 

}; // Foo 

/* Sample use. */ 
static_assert(std::is_same<TTuple<2, NoDefault>, 
          std::tuple<NoDefault, NoDefault>>::value, ""); 

int main() {} 

注:あなたが実際にいくつかの理由でstd::tupleをしたい場合は、そのようにそれを行うことができます、と述べた

ブーストするには、およびstd::tupleの代わりにboost::arrayおよびboost::tuples::tupleがうまくいくでしょう。あなたは:: MPLを取得するためにモル倍どこ

を考えると、あなたの最初の例:あなたが明示的に実行時の容器の中にMPL ::ベクトルを作るための方法を求めているので

5

これは良い、最小限の例のようです、これは可変引数テンプレートやstd::tupleと完全になんとかですが、C++ 11

#include <tuple> 
template <unsigned int N, typename T> 
struct type_repeater { 
    typedef decltype(std::tuple_cat(std::tuple<T>(), typename type_repeater<N-1, T>::type())) type; 
}; 

template <typename T> 
struct type_repeater<0, T> { 
    typedef decltype(std::tuple<>()) type; 
}; 

int main() { 
    type_repeater<3, float>::type asdf; 
    std::get<0>(asdf); 
    std::get<1>(asdf); 
    std::get<2>(asdf); 
} 
+0

ええ、私はこの答えで悩んでいます。 – OmnipotentEntity

+0

タプルを再帰的に繰り返し連結しているので、これはうまくいくかもしれませんが、これは問題ありません。 – Rapptz

+0

これが頭に浮かぶ最初の方法です。再帰を使用しない方法はありますか? – OmnipotentEntity

1

は、私はあなたがBoostyに滞在し、Fusionのas_vectorを使用することをお勧め::ベクトルは、あなたがして使用します。

boost::fusion::result_of::as_vector< 
    mpl::vector<T, T> 
>::type; 

はあなたが望むものであるように思わFusion Vector、取得するには。 Boost Fusionは、コンパイル時と実行時の間のギャップを埋めます。

また、これはプレC++ 11であり、多くの(おそらくほとんどの)プロジェクトでは依然として重要です。

関連する問題