How to use binding with abstract class passed by reference

I am trying to use std :: transform with std :: bind to simplify the loop. Here is the 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 does not compile.

I am using VS2008 SP1 and I got a lot of errors in the templates that I did not understand, so I tried in ideone (gcc 4.7.2). There I have some more readable errors, and I came to the conclusion that this is due to the fact that ITest is abstract.

But I tried to change the way the test object is passed, and if I make it a pointer, it will work .

So, is there anything that I can use to keep the function signature and use a bound transformation instead of a loop?

+4
source share
1 answer

std::bind internally stores the type std::decay ed of each argument. When passing test this leads to an attempt to save an object of type ITest , which, of course, is abstract.

It will work if you pass test wrapped in std::reference_wrapper , as this causes std::bind to store the lvalue reference for the object:

 std::transform(v.begin(), v.end(), back_inserter(vRes), bind(&ITest::Prueba, std::ref(test), _1, 0)); 

You can also pass a pointer to an object, since std::bind accepts this too:

 std::transform(v.begin(), v.end(), back_inserter(vRes), bind(&ITest::Prueba, &test, _1, 0)); 
+4
source

All Articles