6

まず、ここで私の以前の質問と類似していることをお詫びしますが、私は正しいことを尋ねたとは思いません。

私は方法を持っています:

template <typename T>
void some_method( T &t)
{...}

これは、実行時に決定されるタイプを取りfusion::vector<T1, T2, T3, ..., Tn>ます-たとえばvector<int, double>、ある呼び出しとvector<int, double, int>別の呼び出しで。

このベクトルを次のようなもので動的に埋めたい:

int blah = 5;
for(int i = 0; i<size(t); i++){
at_c<i>(t) = blah;
}

at_c はconst.

他のことも試しましたが (前の質問を参照)、これを達成する方法がまだわかりません。

どんな助けでも大歓迎です!ありがとう。

4

3 に答える 3

6

@Mankarse が正しく指定されているため、ループ内fusionでコンテナーを使用することはできません。これは、コンテナーがすべてであり、各要素が他の要素とは異なる型を持つ可能性があるためです。コンテナーを反復処理するすべての関数は、実際にはいくつかの関数であり、通常は次のように実装されます。またはオーバーロードされた関数。したがって、コンテナを から初期化するには、複数の関数 (または単に複数のクラスまたは関数にコンパイルされるテンプレート) が必要です。それらはすべて、そのベクトル (または少なくとも からのイテレータと状態変数にアクセスできます) にアクセスできます。呼び出しごとに増加します)。したがって、2 つのオプションがあります。forfusiontuplefusiontemplatefusionvectorvector

1) boost::fusion::fold を使用します。

template< class StdIteratorT >
struct initialize_fusion_container_from_std_iterator {
    typedef StdIteratorT    result_type;

    template< class T >
    StdIteratorT operator()( StdIteratorT i, T& val ) {
        val = *i;
        return ++i;
    }
};
void use_fold_demo() {
    int p1[] = {4, 5, 6};
    fusion::vector<int, double, int> fv;
    std::vector<int> sv2( p1, p1 + _countof(p1) );
    fusion::fold( fv, sv2.begin(),
    initialize_fusion_container_from_std_iterator<std::vector<int>::iterator>() );
}

2) コンテナーの次の項目で再帰的に自身を呼び出す関数を作成します (この関数の構文は再帰関数に似ていますが、まったく再帰的ではないことを思い出してください):

// this will be called when we reach end of the fusion container(FIBeginT==FIEndT)
template< class FIBeginT, class FIEndT, class StdIteratorT >
void set_fusion_iterator( FIBeginT b, FIEndT e, StdIteratorT i, boost::mpl::true_ )
{
}
// this will be called when FIBeginT != FIEndT
template< class FIBeginT, class FIEndT, class StdIteratorT >
void set_fusion_iterator( FIBeginT b, FIEndT e, StdIteratorT i, boost::mpl::false_ )
{
    *b = *i;
    set_fusion_iterator( fusion::next(b), e, ++i,
        fusion::result_of::equal_to<
            typename fusion::result_of::next<FIBeginT>::type, FIEndT >() );
}

void recursive_function_demo() {
    typedef fusion::vector<int, double, int>    my_fusion_vector;

    int p1[] = {1, 2, 3};
    std::vector<int> sv1( p1, p1 + _countof(p1) );
    fusion::vector<int, double, int> fv;
    set_fusion_iterator( fusion::begin(fv), fusion::end(fv), sv1.begin(),
        fusion::result_of::equal_to<
            typename fusion::result_of::end<my_fusion_vector>::type,
            typename fusion::result_of::begin<my_fusion_vector>::type>() );
}

fusionご覧のように、2 番目のケースははるかに複雑ですが、そのロジックを理解すれば、それを使用してコンテナで何でもできるので、選択はすべてあなた次第です!!

于 2012-10-27T02:38:42.037 に答える
3

boost::fusion::for_eachを使用できます:

#include <boost/fusion/algorithm.hpp>
#include <boost/fusion/container.hpp>

struct F {
    F(int blah): blah(blah){}
    template <typename T>
    void operator()(T& t) const {
        t = blah;
    }
    int blah;
};

template <typename T>
void some_method(T &t)
{
    boost::fusion::for_each(t, F(6));
}

int main() {
    boost::fusion::vector<int, double, int> idi;
    some_method(idi);
    boost::fusion::vector<int, double> id;
    some_method(id);
}

をわかりやすくするためにfor_each、代わりに数値インデックスを使用するほとんど同等のコードを次に示します。

#include <boost/fusion/algorithm.hpp>
#include <boost/fusion/container.hpp>
#include <boost/fusion/sequence.hpp>

template<typename T, int N, int End>
struct some_method_impl {
    void operator()(T& t) const {
        int blah = 6;
        boost::fusion::at_c<N>(t) = blah;
        some_method_impl<T, N+1, End>()(t);
    }
};

template<typename T, int N>
struct some_method_impl<T,N,N> {
    void operator()(T& t) const {}
};


template <typename T>
void some_method(T &t)
{
    some_method_impl<T,0,boost::fusion::result_of::size<T>::type::value>()(t);
}

int main() {
    boost::fusion::vector<int, double, int> idi;
    some_method(idi);
    boost::fusion::vector<int, double> id;
    some_method(id);
}
于 2012-10-27T01:09:01.257 に答える