2010-06-28 50 views
3

我有一个类型列表定义为:使用boost :: MPL ::拉姆达从升压删除类型:: MPL ::基于静态常量成员变量列表

typedef boost::mpl::list<Apple, Pear, Brick> OriginalList; 

我想创建第二个列表不包含任何结果,即从第一个列表形成的结果列表将包含单个类型的Brick。果是通过:所述类型中的定义的静态常量变量,e.g

struct Apple 
{ 
    static const bool IsFruit = true; 
}; 

我目前有涉及创建的元函数的类,并使用boost::mpl::remove_if溶液识别。我相信我应该能够通过使用boost :: mpl :: lambda来取消对单独的RemoveFruit结构的需求,从而使其更加优雅。有关如何做到这一点的任何建议?

的完整代码,因为它目前为:

include <boost/static_assert.hpp> 
#include <boost/mpl/list.hpp> 
#include <boost/mpl/remove_if.hpp> 
#include <boost/mpl/size.hpp> 

#include <iostream> 

struct Apple 
{ 
    static const bool IsFruit = true; 
}; 

struct Pear 
{ 
    static const bool IsFruit = true; 
}; 

struct Brick 
{ 
    static const bool IsFruit = false; 
}; 

typedef boost::mpl::list<Apple, Pear, Brick> OriginalList; 
BOOST_STATIC_ASSERT(boost::mpl::size<OriginalList>::type::value == 3); 

// This is what I would like to get rid of: 
struct RemoveFruit 
{ 
    template <typename T> 
    struct apply 
    { 
    typedef boost::mpl::bool_<T::IsFruit> type; 
    }; 
}; 

// Assuming I can embed some predicate directly in here? 
typedef boost::mpl::remove_if< 
    OriginalList, 
    RemoveFruit 
    >::type NoFruitList; 

BOOST_STATIC_ASSERT(boost::mpl::size<NoFruitList>::type::value == 1); 

int main() 
{ 
    std::cout << "There are " << boost::mpl::size<OriginalList>::type::value << " items in the original list\n"; 
    std::cout << "There are " << boost::mpl::size<NoFruitList>::type::value << " items in the no fruit list\n"; 


    return 0; 
} 
+0

希望我们能有一个元模板,调试器。 :-D – stinky472 2010-06-28 23:26:56

回答

3

我认为你能做的最好的是定义IsFruit结构像

template <typename T> struct isFruit : boost::mpl::bool_<T::IsFruit> {}; 

然后你就可以定义无果列表作为

typedef boost::mpl::remove_if< 
    OriginalList, 
    boost::mpl::lambda< isFruit<boost::mpl::_1> >::type 
    >::type NoFruitList; 

需要额外的结构才能访问类中的IsFruit字段。

请注意,如果您想完全摆脱额外的结构,您必须重命名其他类的布尔成员。如果你遵循了boost :: MPL公约,并呼吁他们value,而不是IsFruit,你可以定义NoFruitList为

typedef boost::mpl::remove_if< 
     OriginalList, 
     boost::mpl::lambda<boost::mpl::_1>::type 
     >::type NoFruitList; 
+0

这很完美。谢谢。只是一个快速跟进问题。我无法将IsFruit重命名为值,但是可以将类型从“static const bool”更改为“boost :: mpl :: bool _ <>'并访问该值? – Shane 2010-06-29 08:36:45

+0

不幸的是,我不知道有什么办法可以做到这一点。本质上,名称'value'由mpl算法在内部使用,以获取任何值字段(就像'type'用于获取类型字段一样)。在这种情况下,lambda将使用value字段来生成一个与RemoveFruit元函数具有相同效果的元函数类。如果你不能重命名,你需要一些其他机制来告诉mpl你想使用哪个字段。在我的示例中,这将是isFruit结构,它将您类的IsFruit字段实际映射到bool_的值字段。 – JRM 2010-06-29 10:41:57

+0

够公平的。谢谢。 – Shane 2010-06-29 11:45:27