Search code examples
c++boostboost-bind

boost::bind to concatenate strings in std::transform


I am trying to concatenate two string using boost::bind inside std::transform

Assuming that my class has two methods to get two strings (first and second) and the conatiner is vector of strings, I am trying to do as follows

struct Myclass
{
   std::string getFirstString() {return string1}
   std::string getSecondString() {return string2}

   private:
     std::string string1;
     std::string string2;
}

Myclass myObj;

std::vector<string > newVec;
std::vector<myObj> oldVec;
std::transform (oldVec.begin(), oldVec.end(), std::back_inserter(newVec), boost::bind(&std::string::append,boost::bind(&getFirstString,  _1),boost::bind(&getSecondString, _1 ) ) ); 

But, I get error saying

error: cannot call member function 'virtual const getSecondString() ' without object

What am I missing here?


Solution

  • You have two problems.

    The first is that you're taking the address of a member function incorrectly. You always have to specify the class, i.e. boost::bind(&Myclass::getFirstString, _1).

    The second is that you're then trying to bind std::string::append, which modifies the object it's called on. You really want operator +. Since you can't bind that directly, use std::plus<std::string> instead. So this is what it should look like:

    std::transform(oldVec.begin(), oldVec.end(),
                   std::back_inserter(newVec),
                   boost::bind(std::plus<std::string>(),
                               boost::bind(&Myclass::getFirstString, _1),
                               boost::bind(&Myclass::getSecondString, _1)
                              )
                  );
    

    Or you can use Boost.Lambda instead. And while you're at it, use Boost.Range, it's awesome.

    namespace rg = boost::range;
    namespace ll = boost::lambda;
    rg::transform(oldVec, std::back_inserter(newVec),
                  ll::bind(&Myclass::getFirstString, ll::_1) +
                      ll::bind(&Myclass::getSecondString, ll::_1));