Я пытаюсь использовать 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 вместо цикла?
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));
Других решений пока нет …