用作函子时boost :: phoenix错误消息

时间:2013-07-04 09:03:49

标签: c++ boost boost-phoenix

我正在尝试学习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> >'

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

2 个答案:

答案 0 :(得分:2)

如上所述,使用凤凰城执行此操作的方法是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)());
}

凤凰城可能很复杂,并且绑定表达式是凤凰城语法扭曲中最令人费解和设计的一些,但老实说,这一点看起来并不那么糟糕。

顺便说一下,C ++ 14的多态lambda将消除凤凰城的大部分。

答案 1 :(得分: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 << " ";
}