Hi I want to (multiply,add,etc) vector by scalar value for example myv1 * 3
, I know I can do a function with a forloop , but is there a way of doing this using STL function? Something like the {Algorithm.h :: transform function }?

- 7,696
- 7
- 30
- 41

- 13,140
- 25
- 80
- 114
6 Answers
Yes, using std::transform
:
std::transform(myv1.begin(), myv1.end(), myv1.begin(),
std::bind(std::multiplies<T>(), std::placeholders::_1, 3));
Before C++17 you could use std::bind1st()
, which was deprecated in C++11.
std::transform(myv1.begin(), myv1.end(), myv1.begin(),
std::bind1st(std::multiplies<T>(), 3));
For the placeholders;
#include <functional>

- 698
- 2
- 9
- 22

- 267,707
- 33
- 569
- 680
-
1Any illumination on what std::bind() is doing in the first example? – wcochran Jan 08 '19 at 23:41
-
6Is this expected to be faster than a loop? – Cyrillm_44 Jul 25 '19 at 02:22
If you can use a valarray
instead of a vector
, it has builtin operators for doing a scalar multiplication.
v *= 3;
If you have to use a vector
, you can indeed use transform
to do the job:
transform(v.begin(), v.end(), v.begin(), _1 * 3);
(assuming you have something similar to Boost.Lambda that allows you to easily create anonymous function objects like _1 * 3
:-P)

- 219,335
- 46
- 382
- 435
-
1Valarrays are the correct solution IMO. With luck, your implementation uses SSE instructions to implement the procedure, making it significantly faster. See http://www.pixelglow.com/macstl/valarray/ for one such implementation of valarray. Unfortunately, its not very widespread, so if you want the advantages of SSE instructions you'll probably have to use compiler intrinsics... – Dragontamer5788 Oct 07 '10 at 19:25
-
1@Dragon: `valarray` is the best STL solution, but it's not very good for high-performance computing because it tends to copy data in memory a lot, and produces sequences of small loops containing single operations which have poor memory access patterns. It is easier to upgrade from `valarray` to a proper expression template system, though. – Potatoswatter Oct 07 '10 at 19:38
Modern C++ solution for your question.
#include <algorithm>
#include <vector>
std::vector<double> myarray;
double myconstant{3.3};
std::transform(myarray.begin(), myarray.end(), myarray.begin(), [&myconstant](auto& c){return c*myconstant;});

- 11,217
- 6
- 43
- 49

- 914
- 2
- 11
- 23
-
I'd make it simpler just an empty capture lambda, and get ride of the const object. After all, this id supposed to be a Kickstarter. – Red.Wave Jan 20 '19 at 19:05
I think for_each
is very apt when you want to traverse a vector and manipulate each element according to some pattern, in this case a simple lambda would suffice:
std::for_each(myv1.begin(), mtv1.end(), [](int &el){el *= 3; });
note that any variable you want to capture for the lambda function to use (say that you e.g. wanted to multiply with some predetermined scalar), goes into the bracket as a reference.

- 121
- 2
- 11
-
3This is not the purpose of `std::for_each`. `std::for_each` applies some (probably stateful) function object to a range and then returns this function object. If you want to transform a range use `std::transform` to make your intent more clear. – sv90 Jan 03 '18 at 11:54
If you had to store the results in a new vector, then you could use the std::transform()
from the <algorithm>
header:
#include <algorithm>
#include <vector>
int main() {
const double scale = 2;
std::vector<double> vec_input{1, 2, 3};
std::vector<double> vec_output(3); // a vector of 3 elements, Initialized to zero
// ~~~
std::transform(vec_input.begin(), vec_input.end(), vec_output.begin(),
[&scale](double element) { return element *= scale; });
// ~~~
return 0;
}
So, what we are saying here is,
- take the values (
element
s) ofvec_input
starting from the beginning (vec_input.begin()
) to the end (vec_input.begin()
),- essentially, with the first two arguments, you specify a range of elements (
[beginning, end)
) to transform, range
- essentially, with the first two arguments, you specify a range of elements (
- pass each
element
to the last argument, lambda expression, - take the output of lambda expression and put it in the
vec_output
starting from the beginning (vec_output.begin()
).- the third argument is to specify the beginning of the destination vector.
The lambda expression
- captures the value of scale factor (
[&scale]
) from outside by reference, - takes as its input a vector element of type double (passed to it by
std::transform()
) - in the body of the function, it returns the final result,
- which, as I mentioned above, will be consequently stored in the
vec_input
.
- which, as I mentioned above, will be consequently stored in the
Final note: Although unnecessary, you could pass lambda expression per below:
[&scale](double element) -> double { return element *= scale; }
It explicitly states that the output of the lambda expression is a double. However, we can omit that, because the compiler, in this case, can deduce the return type by itself.

- 366
- 4
- 11
I know this not STL as you want, but it is something you can adapt as different needs arise.
Below is a template you can use to calculate; 'func' would be the function you want to do: multiply, add, and so on; 'parm' is the second parameter to the 'func'. You can easily extend this to take different func's with more parms of varied types.
template<typename _ITStart, typename _ITEnd, typename _Func , typename _Value >
_ITStart xform(_ITStart its, _ITEnd ite, _Func func, _Value parm)
{
while (its != ite) { *its = func(*its, parm); its++; }
return its;
}
...
int mul(int a, int b) { return a*b; }
vector< int > v;
xform(v.begin(), v.end(), mul, 3); /* will multiply each element of v by 3 */
Also, this is not a 'safe' function, you must do type/value-checking etc. before you use it.

- 7,069
- 9
- 54
- 80
-
This works, but is essentially reinventing the wheel, as `std::transform` already does this for you. – Oliver Charlesworth Oct 07 '10 at 20:58