C++ 如何在运行时填充boost::fusion::vector?

C++ 如何在运行时填充boost::fusion::vector?,c++,boost,boost-fusion,C++,Boost,Boost Fusion,首先,很抱歉我的问题与我之前的问题相似,但我认为我问的不对 我有一个方法: template <typename T> void some_method( T &t) {...} 模板 取消某些方法(T&T) {...} 它将在运行时确定类型fusion::vector——例如,在一个调用中确定vector,在另一个调用中确定vector 我想用如下内容动态填充此向量: int blah = 5; for(int i = 0; i<size(t); i++){ at

首先,很抱歉我的问题与我之前的问题相似,但我认为我问的不对

我有一个方法:

template <typename T>
void some_method( T &t)
{...}
模板
取消某些方法(T&T)
{...}
它将在运行时确定类型
fusion::vector
——例如,在一个调用中确定
vector
,在另一个调用中确定
vector

我想用如下内容动态填充此向量:

int blah = 5;
for(int i = 0; i<size(t); i++){
at_c<i>(t) = blah;
}
int blah=5;
对于(int i=0;i您可以使用:


正如@Mankarse正确指定的那样,您不能在
for
循环中使用
fusion
容器,这是因为
fusion
容器都是关于
tuple
的,每个元素可能有不同于其他元素的类型,所有迭代
fusion
容器的函数实际上都很有趣通常作为
模板
或重载函数实现。因此,为了从
向量
初始化
融合
容器,您应该有多个函数(或者只是一个将被编译为多个类或函数的模板),所有这些函数都可以访问该向量(或者至少是一个来自
向量的迭代器
和一个可以为每次调用增加的状态变量)。因此,您有两个选项:

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>() );
}
模板
结构从标准迭代器初始化融合容器{
typedef StdIteratorT结果_type;
模板
StdIteratorT运算符()(StdIteratorT i、T和val){
val=*i;
return++i;
}
};
无效使用\u折叠\u演示(){
int p1[]={4,5,6};
融合::载体fv;
向量sv2(p1,p1+_计数(p1));
fusion::fold(fv,sv2.begin(),
从标准迭代器()初始化融合容器;
}
2) 编写一个使用容器的下一项递归调用自身的函数(记住此函数的语法类似于递归函数,但它根本不是递归的):

//当我们到达fusion容器(FIBeginT==FIEndT)的末尾时,将调用此函数
模板
无效集融合迭代器(FIBeginT b、FIEndT e、StdIteratorT i、boost::mpl::true)
{
}
//当FIBeginT!=费恩特
模板
无效集融合迭代器(FIBeginT b、FIEndT e、StdIteratorT i、boost::mpl::false)
{
*b=*i;
set_fusion_迭代器(fusion::next(b),e,++i,
fusion::result_of::equal_to<
typename fusion::result_of::next::type,FIEndT>();
}
void递归函数\u demo(){
typedef fusion::vector my_fusion_vector;
int p1[]={1,2,3};
std::向量sv1(p1,p1+_countof(p1));
融合::载体fv;
set_fusion_迭代器(fusion::begin(fv),fusion::end(fv),sv1.begin(),
fusion::result_of::equal_to<
typename fusion::result_of::end::type,
typename fusion::result_of::begin::type>();
}
正如您所看到的,第二种情况要复杂得多,但如果您了解它的逻辑,您可以使用它来处理
fusion
容器,因此选择权归您

这个怎么样

这与上面使用 boost::fusion::for_each

但是当i 用法

main(){
  boost::fusion::vector<int,double,std::string,char> vec(9 ,2.2 ,"aaa" ,'b');
  std::cout << at_n_dynamic<double>(vec, 1) << std::endl; //=> 2.2
}
main(){
boost::fusion::vector向量向量机(9,2.2,“aaa”,“b”);
std::cout();}
}
模板网
at_n_dynamic(Sequence&seq,int n){
fusion_at_n_函子atn(n);
#如果0
//启用此if与上述boost::fusion::for_的情况相同
boost::fusion::for_each(seq,atn);
#否则
//这个递归循环在n处停止,但是boost::fusion::for_每个循环最后停止
在动态融合impl(boost::fusion::begin(seq)、boost::fusion::end(seq)、atn、,
boost::fusion::result_of::equal_to<
typename boost::fusion::result_of::begin::type,
typename boost::fusion::result_of::end::type>();
#恩迪夫
返回atn.value;}
这是 我的文章的副本
什么是
废话
?直接for循环永远不会工作,因为
blah
必须在每次迭代中使用不同的类型(您需要编写递归模板函数)。您能否提供一些示例,说明如何表示要插入的值?我假设要插入的值将被适当地转换为正确的类型。为了便于论证,您可以想象
blah
是一个
int
。它们不会在运行时确定,而是在编译时确定。这非常有用。事实上,你说得很对,我应该更具体地谈谈
诸如此类的事。。。这是一个
向量
,我想把这个
的值映射到fusion::vector。您建议的方法是否可行?@arlogb:是的,序列与一组索引一起,然后在每个
过程中使用索引索引到向量。
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>() );
}
// 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>() );
}
main(){
  boost::fusion::vector<int,double,std::string,char> vec(9 ,2.2 ,"aaa" ,'b');
  std::cout << at_n_dynamic<double>(vec, 1) << std::endl; //=> 2.2
}
#include <boost/fusion/include/vector.hpp>    
template<typename V>
struct fusion_at_n_functor
{
   mutable int i;
   int n;
   mutable V value;
   fusion_at_n_functor(int _n):i(0),n(_n){}
   void operator()(const V & t) const
   { if(i==n){value=t;} i++;}  
   template<typename T>
   void operator()(const T & t) const
   { i++;}
};

template <typename First,typename Last,typename AtN > void
at_n_dynamic_fusion_impl(First i,Last last,AtN &atn,boost::mpl::true_ ){}
template <typename First,typename Last,typename AtN > void
at_n_dynamic_fusion_impl(First i,Last last,AtN &atn,boost::mpl::false_ ){  
  if(atn.i == atn.n ){atn(boost::fusion::deref(i));}
  else{
    atn(boost::fusion::deref(i));
    at_n_dynamic_fusion_impl(boost::fusion::next(i),last,atn,
           boost::fusion::result_of::equal_to<
             typename boost::fusion::result_of::next<First>::type,Last>  ());}
}

template <typename Ret,typename Sequence>  Ret
 at_n_dynamic(Sequence & seq, int n){ 
   fusion_at_n_functor<Ret> atn(n);
#if 0 
  // enabling this if is same to the above case of boost::fusion::for_each 
   boost::fusion::for_each(seq, atn);
#else
  // this recursion loop stop at n. but boost::fusion::for_each stop at last
   at_n_dynamic_fusion_impl(boost::fusion::begin(seq),boost::fusion::end(seq) ,atn,
         boost::fusion::result_of::equal_to<
           typename boost::fusion::result_of::begin<Sequence>::type,
           typename boost::fusion::result_of::end<Sequence>::type>());    
#endif
    return atn.value;}