Question

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?

Was it helpful?

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

OTHER TIPS

In the case you are looking for a fashion way (one line code) to solve your problem, you can do this using for_each and lambdas:

std::for_each(oldVec.begin(), oldVec.end(), [&newVec](Myclass& mc) -> void { newVec.push_back(mc.getFirstString() + mc.getSecondString()); });

using your comment to the first answer, maybe you could use Boost.Foreach:

#include <boost/foreach.hpp>

BOOST_FOREACH(Myclass const& it, oldVec) {
  newVec.push_back(it.getFirstString() + it.getSecondString());
}

btw, your question is badly written, so i'm free to assume that you're actually storing copies of Myclass in the vectors.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top