2012-12-20 73 views
3

下面的boost代碼可以轉換爲純C++ 11標準庫嗎?是這個boost :: tuple代碼可以轉換爲純std ::標準庫代碼嗎?

我看到std::tuplestd::for_each但我似乎無法讓他們玩對方。

我目前使用的是gcc 4.7.2。

CODE

#include <string> 
#include <algorithm> 
#include <iostream> 

#include <boost/fusion/algorithm/iteration/for_each.hpp> 
#include <boost/fusion/include/boost_tuple.hpp> 

struct DoOutput 
{ 
    template<typename T> 
    void operator()(T const& t) const 
    { 
      std::cerr << t << std::endl; 
    } 

    void operator()(std::string const& t) const 
    { 
      std::cerr << "'" << t << "'" << std::endl; 
    } 
}; 

int 
main(int argc, char* argv[]) 
{ 
    boost::tuple< std::string, int > t = boost::make_tuple("foo", 42); 
    boost::fusion::for_each(t, DoOutput()); 

    return 0; 
} 

回答

4

否,代碼是不能直接兌換。

Boost.Fusion是一個用於處理元組的庫,因此它的for_each與元組一起工作,即具有零個或多個異構類型的結構。 std::for_each適用於迭代器範圍,即齊次類型值的範圍。

使用類似index_tuple.h你可以把它改成這樣:

struct sink { 
    template<typename... T> 
    sink(T&&...) { } 
}; 

template<typename T, typename F> 
    int apply(T&& t, F& f) 
    { 
    f(std::forward<T>(t)); 
    return 0; 
    } 

template<typename Tuple, typename F, unsigned... Indices> 
    void apply(Tuple&& t, F&& f, index_tuple<Indices...>) 
    { 
    sink{ apply(std::get<Indices>(std::forward<Tuple>(t)), f)... }; 
    } 

int main() 
{ 
    std::tuple< std::string, int > t = std::make_tuple("foo", 42); 
    apply(t, DoOutput(), make_index_tuple<std::tuple_size<decltype(t)>::value>::type()); 
} 

這將創建一個類型index_tuple<0,1>並調用apply,其推導出參數包Indices{0, 1},然後擴大了包爲:

sink{ apply(std::get<0>(t), f), apply(std::get<1>(t), f) }; 

其中fDoOutput類型的函數對象,並且每個應用調用f(tn)

只需要初始化臨時文件sink,因爲您無法在表達式中展開參數包,例如,這是無效的:

f(std::get<Indices>(t))...; 

因此,而不是包被擴展爲初始化列表中的一個對象的構造,這也保證了包擴張的各要素的順序進行評估。

+3

'的std ::獲得(T)'將無法編譯。 '我'需要編譯時不變。 – Nawaz

+0

drat - 好點 - 修正... –

+0

@Nawaz +1這也是我想的 – kfmfe04

1

否。C++ 11標準庫不包含boost::fusion的功能。你可以期望的最好是適應std::tupleboost::fusion工作:

#include <string> 
#include <algorithm> 
#include <iostream> 

#include <tuple> 

#include <boost/fusion/algorithm/iteration/for_each.hpp> 
#include <boost/fusion/adapted/std_tuple.hpp> //This feature is undocumented 

struct DoOutput 
{ 
    template<typename T> 
    void operator()(T const& t) const 
    { 
      std::cerr << t << std::endl; 
    } 

    void operator()(std::string const& t) const 
    { 
      std::cerr << "'" << t << "'" << std::endl; 
    } 
}; 

int 
main(int argc, char* argv[]) 
{ 
    std::tuple< std::string, int > t = std::make_tuple("foo", 42); 
    boost::fusion::for_each(t, DoOutput()); 

    return 0; 
} 
+0

現在記錄了該功能:http://www.boost.org/doc/libs/1_58_0/libs/fusion/doc/html/fusion/adapted/std__tuple.html – alfC