2013-12-21 50 views
1

我有一個std::arrayboost::fusion::vector<X, Y>,我想傳遞給func1()。此功能將爲每個std::array元素添加一個boost::fusion::vector<X, Y>實例。如何返回boost :: fusion :: vector <x,y,z>添加到std :: array的元素<boost :: fusion :: vector <x,y,z>>?

我必須使用fusion::fold(),以便我可以將正確數量的元素添加到fusion::vector<X,Y>,對吧?

所以我現在有這樣的事情:

void func1(){ 
    boost::fusion::vector<X,Y> my_vec; 
    std::array<boost::fusion::vector<X,Y> > my_array[10]; 
    func2(my_vec, my_array); 
} 

void func2(boost::fusion::vector<X,Y> my_vec, std::array<boost::fusion::vector<X,Y> > my_array){ 

    //THIS IS THE PART I AM UNSURE ABOUT 
    for(int k=0; k<10; k++){ 
     //The first two parameters aren't so important- just included to show the idea 
     my_array[k] = boost::fusion::fold(my_vec, 1, some_struct); 
    } 
} 

//This part is irrelevant 
struct some_struct 
{ 
    typedef int result_type; 

    template<typename T> 
    int operator()(int x, T& t) const 
    { 
     t = something(x); 
     //Not sure if this part needs to return a boost::fusion::vector<X, Y> 
     return x; 
    } 
}; 

我不確定的是如何使用的my_vec簽名,以創建多個boost::fusion::vector<X,Y>實例,並返回他們回來,這樣我可以添加的部分到func2()中的數組。

請問有人請指教?

編輯 - 剛剛發現我得到的第一個參數爲fold()錯誤,修正了我的問題。

回答

3

我不知道我理解你的問題非常好所以首先讓我們來解釋一下什麼是fold,試圖澄清。

一般來說(不僅僅是融合),「摺疊」一個帶有兩個參數的函數將它應用到向量的每個元素以及將函數應用到向量的前一個元素的結果。第一個元素被賦予初始值。

所以,如果我定義函數摺疊爲A f(A, B),這個函數的摺疊將等同於(對於4個元素):

f(f(f(f(A_initial_value, B_0), B_1), B_2), B_3); 

(大寫的前綴是那裏只是爲了執行類型)

現在,更精確地說融合fold。它將摺疊boost::fusion::vector<>內所有元素的功能。作爲boost::fusion::vector<X, Y>相當於std::tuple<X,Y>它會調用f不同類型:

A_final_value = f(A_initial_value, X_value), Y_value); 

所以,當你這樣做:

my_array[k] = boost::fusion::fold(my_vec, 1, some_struct); 

my_array[k]將收到一個數值,因爲這將無法編譯你已經將它定義爲fusion::vector<X,Y>

因此,有試圖澄清fold,我會說沒有你的問題,但我承認我不明白你的意思是「將正確數量的元素添加到fusion::vector<X,Y>」。

編輯:根據更新在搞什麼名堂了評論說。 目標產生這一領域的空白在你std::array<fusion::vector<int, int, int, int>>這樣的斐波那契序列走array的各vector將給以正確的順序斐波那契。

使用fusion您必須通過一個狀態,同時遍歷vector的元素,因此fold是一個不錯的選擇。

這裏是我的這個建議(但開始的第二元素斐波那契序列而不是第一,因爲我沒有刻意去處理的特殊情況......對不起:)):

template <typename Value> 
struct Generator 
{ 
    // Easier to read and mandatory for fold 
    typedef typename std::tuple<Value, Value> result_type; 

    // The function that generate the fibonacci and update the Value 
    result_type operator()(result_type previous, Value& elem) const 
    { 
    elem = std::get<0>(previous) + std::get<1>(previous); 
    return std::make_tuple(std::get<1>(previous), elem); 
    } 
}; 

// Use template to be a bit more generic on array size and vector type 
template <typename Vector, size_t array_size, typename Value> 
void func2(std::array<Vector, array_size>& array, std::tuple<Value, Value> init) 
{ 
    // The state that will be fed across the fold function 
    auto previous = init; 
    for (auto& vect: array) 
    {   
    // Generate the fibonnaci value for every element of the vector starting 
    // from where the state is. The return value of fold is the new state 
    previous = boost::fusion::fold(vect, previous, Generator<Value>()); 
    } 
} 

// Tool to print the vector 
struct Printer 
{ 
    template <typename Elem> 
    void operator()(const Elem& elem) const 
    { 
    std::cout << elem << std::endl; 
    } 
}; 

// Use template to be a bit more generic on array size and vector type 
template <typename Vector, size_t array_size, typename Value> 
void func1(std::tuple<Value, Value> init) 
{  
    // Create the vector 
    std::array<Vector, array_size> array; 

    // FIll it with fibonacci 
    func2(array, init); 

    // Print it 
    for (auto vect: array) 
    {   
    boost::fusion::for_each(vect, Printer()); 
    } 
} 

http://rextester.com/XCXYX58360

+0

我想創建衆多fusion :: vector s,並且這些實例中的每一個都應存儲在std :: array中。這有幫助嗎? – user3125975

+0

@ user3125975是和否。這基本上是你在這裏做的'std :: array > my_array [10];',所以我假設你想以特定的方式初始化它們。爲什麼不只是'my_array [k] = something()'其中'something'是返回一個'fusion :: vector'的函數,你在'somestruct'中調用? – Johan

+0

something()如何知道向量中放入了多少元素?它需要「看」my_vec的格式? – user3125975

相關問題