2013-02-19 71 views
4

請參閱從升壓下面的代碼MPL轉換文檔:升壓轉換MPL序列「真正的」類型

typedef vector<char,short,int,long,float,double> types; 
typedef vector<char*,short*,int*,long*,float*,double*> pointers; 
typedef transform< types,boost::add_pointer<_1> >::type result; 
BOOST_STATIC_ASSERT((equal<result,pointers>::value)); 

我想了解的boost::mpl類型系統和「它實際上是如何工作的。」 據我所知mpl::equal只是比較以下兩個序列的元素,而不是整個序列類型本身。 我不明白爲什麼以下故障:

BOOST_STATIC_ASSERT((std::is_same<result,pointers>::value)); //< assert fails 

爲什麼結果類型不是100%相同的「指針」型? 我認爲這是因爲mpl正在執行轉換懶惰或結果只是一個序列,而不是一個向量? 是否有可能以某種方式強制mpl不再懶惰,並獲得100%相同的類型(我可以用這個結果自己寫一個轉換函數,但我想知道如何在mpl中完成)?

我已經嘗試了一些東西,例如在一個新的載體,但沒有成功插入結果:

BOOST_STATIC_ASSERT((std::is_same< 
    mpl::insert_range< mpl::vector<>, mpl::begin<mpl::vector<> >::type, 
    result >::type, pointers >::value)); //< assert fails too 

而且,我試圖在轉換功能,這也失敗使用back_insert:

typedef transform< types,boost::add_pointer<_1>, 
    mpl::back_inserter< mpl::vector< > > >::type result_new; 
BOOST_STATIC_ASSERT((std::is_same<result_new,pointers>::value)); //< fails... 

讀了「文檔」我沒有幫助。 那麼,是否有可能通過mpl變換(或任何其他變換序列函數)獲得100%相同的類型?什麼是類型的結果

result 

「現實中」,當它不是與指針?

+1

我猜這是'boost :: mpl :: vector'而不是'std :: vector'?使用''''指令時要小心,否則可能會發生衝突,或者在最壞的情況下代碼難以遵循和維護。 – 2013-02-19 18:52:53

+2

http://liveworkspace.org/code/3l8O9K$0 – 2013-02-19 19:26:04

+0

@JoachimPileborg thx指出,它是關於'boost :: mpl :: vector'(代碼來自教程,我不想修改它) 。請注意,我在代碼的其餘部分使用別名'namespace mpl = boost :: mpl;'。 – eci 2013-02-20 08:28:00

回答

7

再次感謝@llonesmiz爲代碼打印使用typeid(),這有助於瞭解發生了什麼。

所以看起來真正的結果類型取決於編譯器(可能是boost #ifdefs),intel編譯器和visual studio將它轉換回std :: vectorN <>其中最大N是boost中的預定義數字(所以它當N太大時不起作用)。 對於g ++,會生成一個mangled類型(即使我的變換調用有2種不同的類型)。

所以我想通過mpl :: equal檢查類型是否正常(檢查範圍的元素)。 如果所有類型應該是「真正」等效(std :: is_same成立),我想你需要手動將結果轉換爲可變模板類std :: tuple。

參見http://liveworkspace.org/code/3l8O9K $ 16 Code Sample

或簡稱:

template < class T, class R > 
struct ToStdTuple; 

template < class... TTypes, class X > 
struct ToStdTuple< std::tuple<TTypes...>, X > 
{ 
    typedef std::tuple< TTypes..., X > type; 
}; 

然後

// typedef mpl::vector<char,short,int,long,float,double> types; 
// typedef mpl::transform< types,boost::add_pointer<mpl::_1> >::type result; 

typedef mpl::fold< result, std::tuple<>, 
    ToStdTuple< mpl::_1, mpl::_2 > >::type result_normalized; 

導致

std::tuple<char*, short*, int*, long*, float*, double*> 

用於ll轉換調用

+1

非常乾淨的解決方案,用於將任何'boost :: mpl'序列轉換爲'std :: tuple'。 ** + 1 ** – etherice 2013-11-06 10:56:55

+0

這實際上是將任何'boost :: mpl'序列轉換爲特定序列類型的完美解決方案...就像'boost :: python :: bases',這是我的目標。不幸的是,我使用的VS2010不支持可變參數模板,但我可以通過'Boost.Preprocessor'解決這個問題。 – Kirinyale 2014-07-11 16:52:37