2010-06-28 52 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