2013-02-26 57 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

相关问题