2013-02-26 47 views
2

我正在嘗試使用boost :: fusion :: vector。但是,我遇到了這個非常簡單的問題。apply boost :: fusion :: for_each boost :: fusion :: vector with mutable function object

#include <iostream> 
#include <string> 

#include <boost/fusion/container/vector.hpp> 
#include <boost/fusion/algorithm.hpp> 

using namespace std; 

struct A{ 
    template <class T> 
    void operator()(const T& t) { 
     x++; 
     cout << t << endl; 
    } 

    int x = 0; 
}; 

int main(){ 
    A a; 
    boost::fusion::vector<int, int, int> tuple{3,4,5}; 
    boost::fusion::for_each(tuple, a); 
} 

注意的struct Aoperator()修改了struct Ax。 gcc 4.7.2警告...... \ include \ boost \ fusion \ algorithm \ iteration \ detail \ for_each.hpp:77:error:將'const A'作爲'void'傳遞給'void A :: operator() (const T &)[with T = int]'丟棄限定符[-fpermissive]

有沒有解決方案?

回答

2

那麼,我沒有使用boost :: fusion,但是從錯誤消息和example from docs看來,for_each期望const對象。即operator()也應該是const。但是你將無法改變對象。

試試這個:

void operator()(const T& t) const { 
    cout << t << endl; 
} 

編輯:

我檢查了源(訴1.53),並聲明是for_each(Sequence& seq, F const& f)。所以確實沒有辦法修改對象本身。我看到的唯一選擇是

既可以使用靜態變量:static int x;

或使用指針:

struct A { 
    template <class T> 
    void operator()(const T& t) const { 
     (*x)++; 
     std::cout << t << std::endl; 
    } 

    int* x; 
}; 

int main() 
{ 
    A a; 
    a.x = new int; 
    *(a.x) = 0; 
    //... 

在這種情況下,要小心應對A情況下,作爲指針將全部指向同一個位置。

+0

感謝。其實,問題是關於迭代元組並應用可以修改的函數對象。從你的回答中,我想我不能使用boost :: fusion來達到這個目的。我對嗎? – Sungmin 2013-02-27 05:25:55

+0

@Sungmin:解決方法是可能的,檢查出更新 – 2013-02-27 07:37:21

+0

感謝您的幫助:) – Sungmin 2013-02-27 08:06:24

1

該解決方案出現在boost :: phoenix :: lambda文檔中。

祕訣就是在函數外部的lambda函數中進行各種計算。

#include <iostream> 

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

#include <boost/phoenix/core.hpp> 
#include <boost/phoenix/operator.hpp> 
#include <boost/phoenix/operator/arithmetic.hpp> 
#include <boost/phoenix/scope/lambda.hpp> 
#include <boost/phoenix/scope/local_variable.hpp> 
#include <boost/phoenix/function.hpp> 
#include <boost/phoenix/fusion.hpp> 

namespace detail { 
    struct A_impl { 
    template<typename T1, typename T2> 
    void operator()(const T1& t1, const T2& t2) const { 
     std::cout << t2 << "," << t1 << std::endl; 
    } 
    }; 
    boost::phoenix::function<A_impl> const A = A_impl(); 
} 

int main() { 
    namespace phx = boost::phoenix; 
    using boost::phoenix::arg_names::arg1; 
    using boost::phoenix::local_names::_a; 
    boost::fusion::vector<int, int, int> tuple{3,4,5}; 
    boost::fusion::for_each(tuple, phx::lambda(_a = 0)[detail::A(arg1,_a++)]); 
} 

短任何語法錯誤,這應該產生:

0,3
1,4
2,5

3

一種更簡單,更好的方法來做到這一點是使用融合::折:

#include <iostream> 

#include <boost/fusion/algorithm/iteration/fold.hpp> 
#include <boost/fusion/include/fold.hpp> 

namespace detail { 
    struct A { 
    typedef int result_type; 
    template<typename T1, typename T2> 
    int operator()(const T1& t1, const T2& t2) const { 
     std::cout << t1 << "," << t2 << std::endl; 
     return t1 + 1; 
    } 
    }; 
} 

int main() { 
    boost::fusion::vector<int, int, int> tuple{3,4,5}; 
    boost::fusion::fold(tuple, 0, detail::A()); 
} 

短任何語法錯誤,這應該產生:

0,3
1,4
2,5

相關問題