2

私は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()のがでstruct A変更xされることに注意してくださいstruct A。gcc 4.7.2は、... \ include \ boost \fusion \ alarmithm \ iteration \ detail \ for_each.hpp:77:エラー:「constA」を「this」引数として「voidA :: operator()(」として渡すことを警告します。 const T&)[with T =int]'は修飾子を破棄します[-fpermissive]

これに対する解決策はありますか?

4

3 に答える 3

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

于 2013-11-25T03:59:20.890 に答える
2

Well, I have not used boost::fusion, but from error message and example from docs, it seems that for_each expects const object. I.e. operator() should be const as well. However you will be unable to mutate object.

Try this:

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

Edit:

I've checked the sources (v. 1.53) and the declaration is for_each(Sequence& seq, F const& f). So there is really no way to modify object itself. The only options I see are

either use static variables: static int x;

or use pointers:

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;
    //...

In this case be careful with coping A instances, as pointers will all point to the same location.

于 2013-02-26T06:20:48.750 に答える
1

解決策は、boost::phoenix::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

于 2013-11-24T03:55:11.697 に答える