Reputation: 5793
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?
Upvotes: 2
Views: 1481
Reputation: 19247
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.
Upvotes: 0
Reputation: 71989
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));
Upvotes: 6
Reputation: 14799
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()); });
Upvotes: 0