Как использовать связывание с абстрактным классом, переданным по ссылке

Я пытаюсь использовать std :: transform с std :: bind, чтобы упростить цикл. Вот некоторый код:

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));
//...
}

Это не компилируется.

Я использую VS2008 SP1, и я получаю много ошибок шаблона, которые я не понимаю, поэтому Я пробовал в идеоне (gcc 4.7.2). Там у меня есть несколько более читаемых ошибок, и я пришел к выводу, что это связано с тем, что ITest является абстрактным.

Но я пытался изменить способ прохождения тестового объекта, и если я это сделаю по указателю, это работает.

Так есть ли что-нибудь, что я могу использовать, чтобы сохранить сигнатуру функции и все еще использовать transform с bind вместо цикла?

4

Решение

std::bind внутренне хранит std::decayтип каждого аргумента. При прохождении test, это приводит к тому, что он пытается сохранить объект типа ITest, что, конечно, абстрактно.

Это будет работать, если вы пройдете test завернутый в std::reference_wrapperкак это вызывает std::bind чтобы сохранить lvalue ссылку на объект:

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

Вы также можете передать указатель на объект, как std::bind принимает это тоже:

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

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]