使用可变函数对象将boost :: fusion :: for_each应用于boost :: fusion :: vector

时间:2013-02-26 01:01:45

标签: c++ boost boost-fusion

我正在尝试使用boost :: fusion :: vector。但是,我遇到了一个非常简单的问题。

#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);
}

请注意operator()的{​​{1}}修改struct A中的x。 gcc 4.7.2警告... \ include \ boost \ fusion \ algorithm \ _ iteration \ detail \ for_each.hpp:77:错误:将“const A”作为'void A :: operator()的'this'参数传递( const T&amp;)[with T = int]'丢弃限定符[-fpermissive]

有解决方法吗?

3 个答案:

答案 0 :(得分:3)

更简单,更好的方法是使用fusion :: fold:

#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

答案 1 :(得分:2)

好吧,我没有使用过boost :: fusion,但是从错误消息和example from docs开始,似乎for_each需要const对象。即operator()也应该是const。但是你将无法改变对象。

试试这个:

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

修改

我检查了来源(v.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个实例,因为指针都会指向同一个位置。

答案 2 :(得分: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