Using std::bind to create a UnaryPredicate out of a BinaryPredicate to use in std::transform

StackOverflow https://stackoverflow.com/questions/18728203

  •  28-06-2022
  •  | 
  •  

Pregunta

I recently encountered this use of for_each:

std::for_each(ts.begin(), ts.end(), [=](T& t){t *= f;});

Well, it works. For a container of Ts and a T f, this multiplies each value by f. However I dislike the use of the lambda here. It's short, but it seems to me that it only duplicates std::multiplies. Additionally, it shouldn't be for_each, but transform, to express the intent of modifying.

However, std::multiplies is a binary predicate, std::transform requires a unary predicate.

I tried to bind f as one parameter, but apparently I'm using it wrong:

std::transform(ts.begin(), ts.end(), std::bind(std::multiplies<T>(), f));

GCC tries to give me a hint with the error message, but I don't see the actual cause:

no matching function for call to ‘transform(std::vector<int>::iterator, std::vector<int>::iterator, std::_Bind_helper<false, std::multiplies<int>, const int&>::type)’

I suspect that I'm using std::bind wrong. What is my mistake?

¿Fue útil?

Solución

You forgot the iterator for result range and a placeholder in bind-expression:

std::transform(
    ts.begin(), ts.end(), // source range
    ts.begin(),           // beginning of result range
    std::bind(std::multiplies<int>(), f, std::placeholders::_1) );
    //                                   ^^^^^^^^^^^^^^^^^^^^^
    //                                   this is where the value from
    //                                   dereferenced source iterator go
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top