I'm trying to use std::transform with std::bind to simplify a loop. Here's some code:
class ITest
{
public:
virtual CPrueba Prueba(double p, double d = 0)const = 0;
};
void foo(const ITest& test)
{
std::vector<double> v;
std::vector<CPrueba> vRes;
// ...
// ...
std::transform(v.begin(), v.end(), back_inserter(vRes),
bind(&ITest::Prueba, test, _1, 0));
//...
}
This doesn't compile.
I'm using VS2008 SP1 and I was getting a lot of template errors I didn't understand, so I've tried in ideone (gcc 4.7.2). There I've got some more readable errors and I've concluded that it had to do with ITest being abstract.
But I've tried by changing how I pass the test object, and if I do it by pointer, it works.
So is there anything I can use to keep the function signature and still use transform with bind, instead of the loop?
std::bind
internally stores the std::decay
ed type of each argument. When passing test
, this results in it attempting to store an object of type ITest
, which is of course abstract.
It will work if you pass test
wrapped in a std::reference_wrapper
, as this causes std::bind
to store an lvalue reference to the object:
std::transform(v.begin(), v.end(), back_inserter(vRes),
bind(&ITest::Prueba, std::ref(test), _1, 0));
You can alternatively pass a pointer to the object, as std::bind
accepts this too:
std::transform(v.begin(), v.end(), back_inserter(vRes),
bind(&ITest::Prueba, &test, _1, 0));