I want to count the number of elements greater than a number in a c++ vector. The threshold value is to be taken input from the user.
The code for counting elements greater than a number is given as:
ctr=count_if(v.begin(),v.end(), greater1);
The corresponding function:
bool greater1(int value)
{
return value >= 8;
}
The problem is I would know the threshold value(here 8) only before the count_if function call so I need to pass the threshold t as a parameter. How to establish the same?
N.B. Only for c++11 standard
The easiest way to do this is to use a lambda expression. Using that you can build a functor (called a Closure Object) in the call site of count_if and you can use what you known then inside the body of the lambda. That would leave you with something like
auto minimum_value = /* something that gets the minimum value you want to use for the comparison */
auto count = std::count_if(v.begin(), v.end(),[&](auto const& val){ return val >= minimum_value; });
// ^ use this to capture a reference of minimum_value
Make a function that gives you the threshold function!
auto above(int threshold) {
// This captures a copy of threshold
return [=](int value) {
return value >= threshold;
};
};
You can then get the count using above, just by passing the threshold as an argument:
auto count = count_if(v.begin(), v.end(), above(8));
Like NathanOliver said, we need to "capture" the threshold value to be used internally. A lambda accomplishes that, but how?
When you write a lambda like
int threshold = 8;
std::count_if(/*...*/, [threshold](int next_val){return next_val >= threshold;});
In C++11 and beyond, the compiler uses this lambda syntax to generate a lightweight class that exposes the function call operator like so:
struct my_greater_equal
{
explicit my_greater_equal(int _threshold) : threshold(_threshold){}
bool operator()(int next_val) const
{
return next_val >= threshold;
}
int threshold;
};
(This is only mostly like what a lambda looks like)
Then an instance is created and used in count_if as-if:
std::count_if(my_collection.cbegin(), my_collection.cend(), my_greater_equal{8});
Internally, std::count_if calls my_greater_equal::operator() for each element in your collection.
Pre-C++11 we had to manually create these lightweight function objects (sometimes called functors even if that's not technically correct)
C++03 Demo
Things are much easier now :-)
Related
I'm trying to better understand the interactions of lambda expressions and iterators.
What is the difference between these three snippets of code? onSelect is an std::function that is called when a component is selected.
Example 1 and 3 seem to work quite nicely. Example 2 returns the same index value, regardless of the component clicked.
My intuition is that Example 2 only results in one symbol being generated, and therefore the function only points to the first value. My question is, why would for_each result in multiple function definitions being generated, and not the normal for loop?
components[0].onSelect = [&]{ cout<<0; };
components[1].onSelect = [&]{ cout<<1; };
components[2].onSelect = [&]{ cout<<2; };
components[3].onSelect = [&]{ cout<<3; };
//And so on
vs
for (int i = 0; i < numComponents; ++i)
{
components[i].onSelect = [&]
{
cout<<components[i];
};
}
vs
int i = 0;
std::for_each (std::begin (components), std::end (components), [&](auto& component)
{
component.onSelect = [&]{
cout<<i;
});
What is the difference between these three snippets of code?
Well, only the first one is legal.
My intuition is that Example 2 only results in one symbol being generated
Each lambda expression generates a unique unnamed class type in the smallest enclosing scope. You have one block scope (inside the for loop) and one lambda expression so yes, there's only one type.
Each instance of that type (one per iteration) could differ in state, because they could all capture different values of i. They don't, though, they all capture exactly the same lexical scope by reference.
and therefore the function only points to the first value
A lambda expression is always a class type, not a function. A lambda expression with an empty capture is convertible to a free function pointer - but you don't have an empty capture. Finally, the lambda didn't capture only the first value - or any value - but an unusable reference to the variable i. Because you explicitly asked to capture by reference ([&]) instead of value.
That is, they all get the same reference to i whatever its particular value at the time they're instantiated, and i will have been set to numComponents and then gone out of scope before any of them can be invoked. So, even if it hadn't gone out of scope, referring to components[i] would almost certainly be Undefined Behaviour. But as it has gone out of scope, it is a dangling reference. This is an impressive density of bugs in a small amount of code.
Compare the minimal change:
for (int i = 0; i < numComponents; ++i) {
components[i].onSelect = [i, &components]
{
cout<<components[i];
};
}
which captures i by value, which is presumably what you really wanted, and only takes components by reference. This works correctly with no UB.
My question is, why would for_each result in multiple function definitions being generated, and not the normal for loop?
You have two nested lambda expressions in example 3, but we're only concerned with the inner one. That's still a single lambda expression in a single scope, so it's only generating one class type. The main difference is that the i to which it has (again) captured a reference, has presumably not gone out of scope by the time you try calling the lambda.
For example, if you actually wrote (and a minimal reproducible example would have shown this explicitly)
int i = 0;
std::for_each (std::begin (components), std::end (components), [&](auto& component)
{
component.onSelect = [&]{
cout<<i;
});
for (i = 0; i < numComponents; ++i)
components[i].onSelect();
then the reason it would appear to work is that i happens to hold the expected value whenever you call the lambda. Each copy of it still has a reference to the same local variable i though. You can demonstrate this by simply writing something like:
int i = 0;
std::for_each (std::begin (components), std::end (components), [&](auto& component)
{
component.onSelect = [&]{
cout<<i;
});
components[0].onSelect();
components[1].onSelect();
i = 2;
components[1].onSelect();
The following function is supposed to take the coefficients of a polynomial and create a function of time from them:
std::function<double(double)> to_equation(const std::vector<double>& coefficients)
{
return [coefficients](double t)
{
auto total = 0.0;
for (int i = 0; i < coefficients.size(); i++)
{
total += coefficients[i] * pow(t,i);
return total;
}
};
}
It should be usable as follows:
std::vector<double> coefficients = {1.0,2.0,3.0};
auto f = to_equation(coefficients);
auto value = f(t);
The code does however not work as intended, since at the time of execution of f(t), not the coefficients passed to to_equation(coefficients) are used, but some totally different values magically captured from the context. What is happening and how can I fix that?
Well, you are returning a lambda that capture coefficients by value. If you pass some vector to the to_equation function, all values will be copied, and the lambda won't refer to the original vector anymore.
I suggest this solution:
// auto is faster than std::function
auto to_equation(const std::vector<double>& coefficients)
{
// Here, you capture by reference.
// The lambda will use the vector passed in coefficients
return [&coefficients](double t)
{
// ...
};
}
However, you must sometime deal with code like this:
std::function<double(double)> f;
{
std::vector<double> coeff{0.2, 0.4, 9.8};
f = to_equation(coeff);
}
auto result = f(3);
This is bad, the vector coeff don't live long enough, and we refer to it after the vector is destroyed.
I suggest adding this overload to your function:
// when a vector is moved into coefficients, move it to the lambda
auto to_equation(std::vector<double>&& coefficients)
{
// Here, you capture by value.
// The lambda will use it's own copy.
return [coeff = std::move(coefficients)](double t)
{
// ...
};
}
Then, calling your function is possible in both ways:
std::vector<double> coeff{0.2, 0.4, 9.8};
auto f1 = to_equation(coeff); // uses reference to coeff
auto f2 = to_equation({0.2, 0.4, 9.8}) // uses value moved into the lambda
You can capture by reference, instead of by value. But, of course, if the underlying vector goes out of scope and gets destroyed before the lambda gets invoked, you'll have a big mess on your hands.
The safest course of action is to use a std::shared_ptr<std::vector<double>> instead of a plain vector, and capture that by value. Then, the lambda will always, essentially, feed on whatever were the most recent set of coefficients, and won't blow up if it gets called after all other references to the underlying vector, from whatever code computed them, go out of scope.
(Of course, you have to keep in mind what's going to happen here if the lambda gets copied around, since all copies of the original lambda will be using the same vector).
For more information, open the chapter of your C++ book that explains the difference between capturing by value and by reference, when using lambdas.
Is there any way to check if all conditions are met?
e.g:
if(num[i] > (*all*)alt[c])
{
}
Instead of doing it this way
if(num[i] > alt[1] && num[i] > alt[2] && num[i] > alt[3])
{
}
Like is there a shorter way?
You could use a suitable auxiliary function which effectively just calls one of the algorithms, e.g.:
if (is_bigger(num[i], alts)) {
// ...
}
where the function is_bigger() just uses std::all_of() with a suitable condition:
template <typename T, typename Sequence>
bool is_bigger(T const& test, Sequence const& alts) {
return std::all_of(alts.begin(), alts.end(),
[&](T const& other){ return test > other; });
}
all_of() is simple an algorithm which applies a predicate to all elements in the sequence delimited by the begin and end iterator (alts.begin() and alts.end()). The other thing in this function is simple a lambda expression creating a corresponding predicate.
Well, you can take the maximum of all alts, and then compare num[i] to it.
Get the maximum element with:
auto max = std::max_element(alt.begin(), alt.end());
For now no, at least without creating additional code (instead of evaluating at compile-time). But if you use 'inline' variables (currently only an early draft - idea of mine), you could write:
auto FuncCheckingMulCond(auto &inline varSrc, auto &inline varTarget, inline size_t nTimes)
{
for(inline size_t i(0); i < nTimes; ++i)
if(!(varSrc > varTarget[i]))
return false;
return true;
}
And so your example will look like this:
if(FuncCheckingMulCond(num[i], alt, 5))
{
}
Inline variables should be such which value is known at compile-time and as 'FuncCheckingMulCond' contain 'inline' parameters it should be evaluated at compile-time too. '&inline' is an inline reference which means that it instead of storing some pointer, all it's instances are replaced with the variable it had bound to. So in theory - the above code should do exactly the thing you wanted, but unfortunately this isn't part of ISO C++ yet.
For lambda expressions, I don't quite get the usefulness of closures in C++11.
auto f = [] (int n, int m) { return n + m };
std::cout << f(2,2);
versus.
int n = 2;
auto f = [n] (int m) { return n + m };
std::cout << f(2);
This is a very basic and primitive example. I'm guessing that closures play an important part in other kinds of statements, but my C++ book doesn't clarify this (so far).
Why not include the closure as a parameter?
OK, a simple example, remove all the x's from a string
char x = 'x';
std::string s = "Text to remove all 'x's from";
s.erase(std::remove_if(s.begin(), s.end(), [x](char c) {return x == c;}), s.end());
Borrowed and modifed from http://en.cppreference.com/w/cpp/algorithm/remove
In this example, remove_if() only takes a single parameter, but I need two values for the comparison.
Closures are not always called immediately. They are objects which can be stored and called later when the data necessary to successfully execute the lambda function may no longer be in scope or easily accessible from the call site.
It's possible to to store any necessary data along with the closure but it's so much simpler for the closure to grab anything it needs when it's created and use it when it's eventually called. It provides a form of encapsulation.
This also decreases code coupling because if you were to store the data along with the code then the caller could only work with the specific objects you decided to store. Since a closure carries its own data along with it, it can work with any data it needs.
Here's an greatly oversimplified real-life example. I built a database server which needed to support fields with multiple values. The problem was that when results were displayed, it was important to highlight which values actually caused a record to match the search criteria. So, the query parser would spit out a predicate in the form of a closure which would indicate whether or not it was a matching value.
It looked something like this:
std::function< bool(int value) > parser::match_int(int search_val) {
return [=](int value) { value == search_val; };
}
That closure got stored in a collection. When it was time to render the record, I could easily determine which values needed to be highlighted. Keep in mind that the parser and any associated data is now gone:
void render_values(std::function< bool(int value) > pred, std::vector<int> values) {
for (int value : values) {
if (pred(value))
render_highlight(value);
else
render_normal(value);
}
}
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 }?
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>
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)
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;});
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.
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 (elements) of vec_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
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.
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.
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.