2013-06-05 65 views
0

我想學習C++模板元編程。給定一個boost :: mpl ::類的向量我想計算該類的索引,其中一個靜態成員變量具有特定的值。boost-mpl,摺疊和佔位符,從向量中選擇類

我找到了一個似乎可行的解決方案。但是,爲了正確編譯,我需要一些看似不必要的奇怪'包裝類'。這裏是我的代碼:

#include <iostream> 
#include <boost/mpl/vector.hpp> 
#include <boost/mpl/size.hpp> 
#include <boost/mpl/at.hpp> 
#include <boost/mpl/int.hpp> 
#include <boost/mpl/fold.hpp> 
#include <boost/mpl/range_c.hpp> 

using namespace boost; 

template<typename T> 
struct get_ind { 
    typedef mpl::int_<T::type::value> type; 
}; 

template <typename T> 
struct get_x { 
typedef mpl::int_<T::x> type; 
}; 

template<typename l> 
struct clist { 
typedef mpl::range_c<int, 0, mpl::size<l>::type::value > indices; 
typedef mpl::fold< 
    indices, mpl::size<l>, 
    mpl::if_< 
     is_same< 

// HERE: 
    get_x<mpl::at<l, get_ind<mpl::placeholders::_2> > > 
// 
// mpl::int_< mpl::at<l, mpl::placeholders::_2>::type::x > 
// mpl::int_<mpl::at<l, mpl::placeholders::_2> >::x > 
     , mpl::int_<1> > 
        , 
    mpl::placeholders::_2, mpl::placeholders::_1 > 
> index; 
}; 


struct A { 
static const int x = 1; 
}; 

struct B { 
static const int x = 0; 
}; 


int main(int argc, char*argv[]) { 

typedef boost::mpl::vector<A, B> classes; 
typedef clist<classes> classlist; 

std::cout << "result " << classlist::index::type::value<<std::endl; 
return 0; 
} 

編輯:

我已經使舒爾它實際上編譯。但是,史蒂文的建議也行不通。對於這種變化,我得到這些錯誤:

test.cpp: In instantiation of ‘clist<boost::mpl::vector<A, B, mpl_::na, mpl_::na,  
mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_  
::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> >’: 
test.cpp:56: instantiated from here 
test.cpp:38: error: ‘x’ is not a member of ‘mpl_::void_’ 
test.cpp: In function ‘int main(int, char**)’: 
test.cpp:56: error: ‘classlist::index’ is not a class or namespace 

任何人都可以請向我解釋什麼是錯誤的,我第一個解決方案(註釋),我怎樣才能避免需要上課get_x和get_ind?

千恩萬謝

+0

在我的環境中它不能編譯。請添加'#include '和'使用命名空間提升;'在另一個包含之後。在添加這個並嘗試你的其他變體之後,除了很多其他的錯誤外,結果是一個語法錯誤。在工作解決方案中有3'<' and 3 '>',而不工作的是2'<' and 3 '>'。你必須解決這個問題,我認爲你應該在格式化和記錄方面做更多的工作。 –

回答

1

基於錯誤信息,它看起來像你需要像

mpl::int_< mpl::at<l, mpl::placeholders::_2>::type::x > > 
1

我們需要傳遞一個元函數來if_這是可以做到的懶惰評估後折擴大。

mpl::int_< mpl::at<l, mpl::placeholders::_2>::type::x > 

就會馬上做評估,其產生的不能表達找到「X」的錯誤。

您可以嘗試使用服裝測試功能而不是is_same,例如,

template <typename T, typename V> 
struct has_value 
    : mpl::bool_<T::x == V::value> 
{}; 

template<typename l> 
struct clist { 
    typedef mpl::range_c<int, 0, mpl::size<l>::type::value > indices; 
    typedef mpl::fold< 
    indices, mpl::size<l>, 
    mpl::if_< 
     has_value< 
     mpl::at<l, mpl::placeholders::_2> 
     , mpl::int_<1> > 
     , 
     mpl::placeholders::_2, mpl::placeholders::_1 > 
    > index; 
};