什么是遍历一个boost :: MPL ::列表中惯用的方法是什么? [英] What's the idiomatic way to traverse a boost::mpl::list?

查看:377
本文介绍了什么是遍历一个boost :: MPL ::列表中惯用的方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:我编辑的样品,以便更好地像我有问题,现在该函数依赖于常规参数(而不是只对模板参数),这意味着计算的不能在编译时进行。


我写了一些code书面手类型串,现在我们已经开始使用提高,我试图将它移动到 MPL 库。

我似乎无法找到 MPL ::列表任何像样的文档和我甚至未能端口code到的boost :: MPL 。我有,即使(如果?)我做移植code它仍然不会成功惯用的感觉。可以请你让我知道如何在下列情况应升压写入(注意,这是不实际的code,这是一个人为的简化)。

原文code (codepad.org贴)

 类零{};模板<类头,尾类=零>
结构TYPE_LIST {
    typedef的头头;
    尾部的typedef尾;
};模板<类列表>
结构foo的;模板<类头,尾班GT&;
结构美孚<&TYPE_LIST LT;头,尾> > {
    模板<类T>
    静态无效*栏(T * OBJ,为size_t大小)
    {
        如果(sizeof的(头)==大小)
            返回reinter pret_cast<头* GT;(OBJ);        //否则,检查列表的其余部分
        返回富<尾> ::巴​​(OBJ,大小);
    }
};
模板<>
结构美孚<&零GT;
{
    模板<类T>
    静态无效*栏(T *,为size_t){返回NULL; }
};#包括LT&;&iostream的GT;诠释的main()
{
    INT N = 3;
    无效* P =富<&TYPE_LIST LT;焦炭,TYPE_LIST< BOOL,
                      TYPE_LIST<双,TYPE_LIST<长> > > >
                 > ::巴​​(&放大器; N,4);
    性病::法院LT&;< P<<的std :: ENDL;
}

失败的尝试使用升压 (codepad.org贴)

 的#include<提升/ MPL / list.hpp>模板<类列表>
结构foo的{
    模板<类T>
    静态无效*栏(T * OBJ,为size_t大小)
    {
        的typedef typename的提振:: MPL ::前<列表> ::类型类型;
        如果(的sizeof(型)==尺寸)
            返回reinter pret_cast<键入*>(OBJ);        //否则,检查列表的其余部分
    返回富< typename的名单::接下来> ::巴​​(OBJ,大小);
  }
};模板<>
结构美孚<提高:: MPL :: list0<提高:: MPL ::呐> >
{
    模板<类T>
    静态无效*栏(T *)
    {
        返回NULL;
    }
};#包括LT&;&iostream的GT;诠释的main()
{
    INT N = 3;
    无效* P =富<提高:: MPL ::名单<焦炭,布尔人,双人,长> > ::巴​​(&放大器; N,4);
    性病::法院LT&;< P<<的std :: ENDL;
}


使用的 的boost :: MPL ::折叠 是这样的:

 的#include<提升/ MPL / list.hpp>
#包括LT&;提升/ MPL / fold.hpp>#包括LT&;&iostream的GT;使用空间boost :: MPL;//初始状态:
结构foo_start {
    模板< typename的T>
    静态无效*栏(T *,为size_t){返回0; }
};//折叠步骤:将它添加到preV
模板< typename的preV,类型名的这家>
结构foo_iteration {
    结构类型{
        模板< typename的T>
        静态无效*栏(T * OBJ,为size_t大小){
            如果(sizeof的(这)==大小)
                返回reinter pret_cast<该* GT;(OBJ);
            其他
                返回$ P $光伏::巴(OBJ,大小);
        }
    };
};// foo的只是调用MPL ::现在折叠:
模板< typename的列表>
结构富:褶皱<列表,foo_start,foo_iteration&所述; _,_> > ::类型{};诠释主(){
    INT N = 3;
    无效* P =富<名单<焦炭,布尔人,双人,长> > ::巴​​(&放大器; N,4);
    性病::法院LT&;< P<<的std :: ENDL;
}

打印 0 在这里,后来我在AMD64,所以我需要改变 4 来的 8 ,并获得一些非零。

心连心

Edit: I've edited the sample to better resemble the problem I have, now the function depends on a regular parameter (and not only on template parameters) which means that the computations can't be made at compile time.


I wrote some code with a hand written typelist and now we've started using boost and I'm trying to move it to the mpl library.

I can't seem to find any decent documentation for mpl::list and I'm even failing to port the code to boost::mpl. I've got the feeling that even when (if?) I do succeed in porting the code it will still not be idiomatic. Can' you please let me know how the following should be written with boost (note that this is not the actual code, it's a contrived simplification).

Original code (codepad.org paste)

class nil {};

template <class Head, class Tail = nil>
struct type_list {
    typedef Head head;
    typedef Tail tail;
};

template <class List>
struct foo;

template <class Head, class Tail>
struct foo<type_list<Head, Tail> >{
    template <class T>
    static void* bar(T* obj, size_t size)
    {
        if (sizeof(Head) == size) 
            return reinterpret_cast<Head*>(obj);

        // Otherwise check the rest of the list
        return foo<Tail>::bar(obj, size);
    }
};


template <>
struct foo<nil>
{
    template <class T>
    static void* bar(T*, size_t)  { return NULL; }
};

#include <iostream>

int main()
{
    int n = 3;
    void *p = foo<type_list<char, type_list<bool, 
                      type_list<double, type_list<long> > > >
                 >::bar(&n, 4); 
    std::cout<< p << std::endl;
}

Failed Attempt to use Boost (codepad.org paste)

#include <boost/mpl/list.hpp>

template <class List>
struct foo{
    template <class T>
    static void* bar(T* obj, size_t size)
    {
        typedef typename boost::mpl::front<List>::type type;
        if (sizeof(type) == size) 
            return reinterpret_cast<type*>(obj);

        // Otherwise check the rest of the list
    return foo<typename List::next>::bar(obj, size);
  }
};

template <>
struct foo<boost::mpl::list0<boost::mpl::na> >
{
    template <class T>
    static void* bar(T*)
    {
        return NULL;
    }
};

#include <iostream>

int main()
{
    int n = 3;
    void *p = foo<boost::mpl::list<char, bool, double, long> >::bar(&n, 4);
    std::cout << p << std::endl;
}

解决方案

Use boost::mpl::fold like this:

#include <boost/mpl/list.hpp>
#include <boost/mpl/fold.hpp>

#include <iostream>

using namespace boost::mpl;

// Initial state:
struct foo_start {
    template <typename T>
    static void * bar( T *, size_t ) { return 0; }
};

// Folding Step: add This to Prev
template <typename Prev, typename This>
struct foo_iteration {
    struct type {
        template <typename T>
        static void * bar( T * obj, size_t size ) {
            if ( sizeof(This) == size )
                return reinterpret_cast<This*>(obj);
            else
                return Prev::bar( obj, size );
        }
    };
};

// foo is just calling mpl::fold now:
template <typename List>
struct foo : fold< List, foo_start, foo_iteration<_,_> >::type {};

int main() {
    int n = 3;
    void * p = foo< list<char, bool, double, long> >::bar( &n, 4 );
    std::cout << p << std::endl;
}

Prints 0 here, but then I'm on amd64, so I need to change the 4 to an 8, and get something non-zero.

HTH

这篇关于什么是遍历一个boost :: MPL ::列表中惯用的方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆