Pregunta

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?

¿Fue útil?

Solución

std::bind internally stores the std::decayed 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));
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top