1

我正在尝试学习 boost::phoenix 并尝试在 std::transform 中使用它,如下所示。

class myClass
{
   int i;

public:
   getNumber(); 
   setNumber(int j); 
};

int main()
{
   std::vector<myClass*> vect
   std::vector<int> numVect

   numVect.resize(vect.size());
   using boost::phoenix::arg_names::arg1;
   std::transform (vect.begin(), vect.end(), numVect.begin(), arg1->getNumber());
}

但是,我收到一个错误error: base operand of '->' has non-pointer type 'const boost::phoenix::actor<boost::phoenix::argument<0> >'

我不太确定这是什么意思。任何帮助都会很棒。谢谢

4

2 回答 2

2

正如您在上面提到的,使用 Phoenix 执行此操作的方法是使用phoenix::bind或与->*您在上面所做的一样:

#include <vector>
#include <boost/phoenix/core.hpp>
#include <boost/phoenix/operator.hpp>
#include <boost/range/algorithm/transform.hpp>

class myClass
{
    int i;

public:
    int getNumber() { return i; }
    void setNumber(int j) { i = j; }
};

int main()
{
   std::vector<myClass*> vect;
   std::vector<int> numVect;

   using boost::phoenix::arg_names::arg1;
   boost::transform(vect,
                    std::back_inserter(numVect),
                    (arg1->*&myClass::getNumber)());
}

Phoenix 可能很复杂,bind 表达式是 Phoenix 语法扭曲中最令人费解和做作的一些,但老实说,这似乎并没有那么糟糕。

顺便说一句,C++14 的多态 lambda 将消除 Phoenix 的大部分内容。

于 2013-07-04T17:29:30.190 回答
0

我会用

std::transform (vect.begin(), vect.end(), numVect.begin(), phx::bind(&myClass::getNumber, arg1));

或者,如果您想要更好的语法:

auto getNumber = phx::lambda [ phx::bind(&myClass::getNumber, arg1) ];
std::transform (vect.begin(), vect.end(), numVect.begin(), getNumber(arg1));

演示:

#include <vector>
#include <algorithm>
#include <iostream>
#include <boost/phoenix/phoenix.hpp>

namespace phx = boost::phoenix;

struct myClass
{
   int i;

   int getNumber() const { return i; }
   void setNumber(int j) { i = j; }
};

using namespace boost::phoenix::arg_names;
static const auto getNumber = phx::lambda [ phx::bind(&myClass::getNumber, arg1) ];

int main()
{
   const std::vector<myClass*> vect { new myClass{1}, new myClass{2}, new myClass{42} };
   std::vector<int> numVect(vect.size());

   // puritan/standard version:
   std::transform (vect.begin(), vect.end(), numVect.begin(), std::mem_fn(&myClass::getNumber));

   // just bind:
   std::transform (vect.begin(), vect.end(), numVect.begin(), phx::bind(&myClass::getNumber, arg1));

   // using more natural syntax
   std::transform (vect.begin(), vect.end(), numVect.begin(), getNumber(arg1));

   for(auto i : numVect)
       std::cout << i << " ";
}
于 2013-07-04T23:05:23.173 回答