I have a question about the for_each in vector, the code is following:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
struct myclass {
void operator() (int i) {cout << " " << i;}
} myobject;
int main () {
vector<int> myvector(3,4);
cout << "\nmyvector contains:";
for_each (myvector.begin(), myvector.end(), myobject);
cout << endl;
return 0;
}
should the third argument of for_each() be a function name?
if we pass the name of the struct, how does this works?
This is a functor.
std::for_each is a function template that basically expands to this:
for (iter = myvector.begin(); iter != myvector.end(); ++iter)
{
myobject(*iter);
}
So myobject can either be a function pointer, or it can be an object with an overload for operator().
The third argument of for_each can be anything that behaves like a function, i.e. that can be invoked like x(). Since your struct overloads operator(), it has precisely this behaviour.
Classes which overload the ()-operator are called "functors" or "function objects". Their power lies in the fact that you can store additional data (e.g. accumulators or inital values) in the class members while still behaving like an ordinary function.
Not necessarily. for_each expects an object that can be called like a function (a functor). In other words, an object that overloads operator()(T) where T is the type of the values held in the container on which for_each is applied.
You are not passing a type or (quote) "name of a struct", but rather an object. The syntax
struct Foo {
} foo;
actually declares the type Foo and on object foo of type Foo.
Passing function objects instead of function pointers is prefered. See also
this about why.
The code is pretty well explained where, I think, you found it:
The source of the code.
The example on the site looks like this:
// for_each example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
void myfunction (int i) {
cout << " " << i;
}
struct myclass {
void operator() (int i) {cout << " " << i;}
} myobject;
int main () {
vector<int> myvector;
myvector.push_back(10);
myvector.push_back(20);
myvector.push_back(30);
cout << "myvector contains:";
for_each (myvector.begin(), myvector.end(), myfunction);
// or:
cout << "\nmyvector contains:";
for_each (myvector.begin(), myvector.end(), myobject);
cout << endl;
return 0;
}
It's not a function name, it's a function object (functor).
You can either do this manually yourself by defining a class with suitable operator() implementation, or wrap a function as a functor using Boost.Function or similar.
Note that there is a subtle issue here. If you define your operator() as you have here, the code works, but cannot be used to update the vector elements. If you wish to update in place, you need to define instead as (for example):
void operator() (int& i) { i *= 2; }
This is more typically how functors are defined - arguments are passed by reference rather than by value.
Since you are overloading operator () (int) for myclass, the function name is resolved from the struct itself. See for_each for more info.
Related
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
template <class T>
class Sum {
public:
Sum(T i = 0) : res(i) {}
void operator()(T x) { res =res + x; }
T result() const { return res; }
private:
T res;
};
int main() {
Sum<int> s;
vector<int> vec;
vec.insert(vec.begin(), 10);
vec.insert(vec.begin()+1, 10);
vec.insert(vec.begin()+2, 10);
vector<int>::iterator itr = vec.begin();
cout << *itr << endl;
for_each(vec.begin(), vec.end(), s);
cout << "sum is" << s.result() << endl;
return 0;
}
This is my code. I want to add vec values in class Sum res. for_each should be calling s's operator(), so the result should be 30, but it shows 0.
I think adding value in vector has no problem. Why is the s.operator() is not working?
for_each takes its third argument by value which means every invocation of operator() affects a completely separate copy of s. There's an algorithm for exactly what you're doing called std::accumulate, but if you want this to work with for_each you need to pass s "by reference" by using std::ref from <functional>.
for_each(vec.begin(), vec.end(), ref(s));
for_each returns a copy of the passed-in functor that provides the "result" of the iteration (whatever the result is). Change your call to:
auto s = for_each(vec.begin(), vec.end(), Sum<int>());
Below is a simple example, with stuff that bugs me. Also a link to an online c++ compiler with given example is here https://ide.geeksforgeeks.org/oxQd8FU2NV
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
template <class T>
void PrintF (const T& printInt) { cout << printInt << " "; }
template <class T>
class PrintClass {
public:
void operator()(T elem) const {
cout << elem << " ";
}
};
int main () {
vector<int> vect;
for (int i=1; i<10; ++i) {
vect.push_back(i);
}
for_each (vect.begin(), vect.end(), PrintClass<int>()); cout << endl;
for_each (vect.begin(), vect.end(), PrintF<int>); cout << endl;
// for_each (vect.begin(), vect.end(), PrintF<int>() );
// won't compile because of () in PrintF<int>()
return 0;
}
Why can't we write PrintClass<int>() without (), like this PrintClass<int> (first for_each line) ?
And when using function (not function object) we must not use () (second for_each line),so we write like this PrintF<int> ?
How should I interpret/parse the 3rd argument in these two for_each functions ?
std::for_each requires an object that can be used like a function. When you use
for_each (vect.begin(), vect.end(), PrintF<int>);
PrintF<int> decays to a pointer to the PrintF<int> function and then for_each can use that pointer to call the PrintF<int> function.
In
for_each (vect.begin(), vect.end(), PrintClass<int>());
PrintClass<int> is the name of a class, it isn't an object. You need the () at the end to tell the compiler to make a temporary object of the type PrintClass<int> and then for_each can use that object to call its operator ().
PrintF<int> is a function. We're passing the function to for_each. Putting parentheses would be incorrect, as we'd be attempting to (unsuccessfully) call the function.
PrintClass<int> is a class. We can't pass classes around, as they're not values. We can, however, pass instances of that class around, so we make an instance of the class and pass it. The following two calls would have the same result
for_each (vect.begin(), vect.end(), PrintClass<int>());
PrintClass<int> myFunction = PrintClass<int>();
for_each (vect.begin(), vect.end(), myFunction);
I'm writing a simple test to see how C++11 Lambdas can be used for the purpose of maximizing code reuse. I have a function, fill_vector() and in one case I'd like it to simply fill a vector with random numbers, but in another case I'd like it to also provide me with the maximum of those numbers.
Here's what I have so far:
#include <iostream>
#include <random>
#include <vector>
#include <algorithm>
#include <iterator>
template <class Function>
void fill_vector(std::vector<int> &v, Function side)
{
for(auto i=v.begin(); i!=v.end(); ++i)
{
*i = rand() % 100;
}
side.lambda(v);
}
class null_test
{
public:
constexpr static auto lambda = [] (std::vector<int> x) { };
};
class test
{
public:
test() : max(0) { }
int max;
static auto lambda = [=] (std::vector<int> x) { max =
std::max_element(x.begin(),x.end()); };
};
int main()
{
std::vector<int> v(20);
null_test n;
fill_vector(v,n);
std::copy(v.begin(),v.end(),std::ostream_iterator<int>(std::cout," "));
std::cout << std::endl;
std::vector<int> v2(20);
test t;
fill_vector(v2,t);
std::copy(v.begin(),v.end(),std::ostream_iterator<int>(std::cout," "));
std::cout << std::endl;
std::cout << t.max << std::endl;
return 0;
}
Which results in the error: ‘this’ was not captured for this lambda function, pointing at my lambda defined in test. I've tried all sorts of capture statements and can't seem to get anything to work. What am I missing?
Also, is it possible to use a lambda inside the loop of fill_vector that could, say, extract every nth element filled? My goal here is to be able to reuse a function like fill_vector as much as possible for other functions that might need slight variations of it in a bigger project.
Looking at your class test:
class test
{
public:
int max;
static auto lambda = [=] (std::vector<int> x) {
max = std::max_element(x.begin(),x.end());
};
};
There are several problems here:
operator() on a lambda is const, and you are trying to modify a member.
You are trying to assign the value to an external variable, but are capturing it by-value, so even if you made the lambda mutable, nothing would happen.
You are trying to assign a member of a class using a static function that does not take an instance of that class.
As dyp points out, std::max_element returns an iterator, not the actual element.
The lambda you want to write probably looks like this:
test t;
std::vector<int> v2(20);
fill_vector(v2, [&t](const std::vector<int>& x){
t.max = *std::max_element(x.begin(), x.end());
});
Just change your fill_vector() function to take a callable, rather than something that has a callable.
I used lambda function to pass it to std::condition_variable wait() function, but that is not the case. I use lambda functions that don't receive any parameters, and everything is absolutely clear for me. But I totally don't understand how is used lamdba function that have parameters list. Show lambda with parameters are used? How to pass parameters to them?
Show lambda with parameters are used? How to pass parameters to them?
It works exactly like with any other type of callable object:
#include <iostream>
int main()
{
auto l = [] (int i) { std::cout << "The answer is " << i; };
l(42);
}
Also notice, that you do not need to store a lambda in a variable in order to invoke it. The following is an alternative way to rewrite the above program:
#include <iostream>
int main()
{
[] (int i) { std::cout << "The answer is " << i; } (42);
// ^^^^
// Invoked immediately!
}
The type of a lambda function (the so-called "lambda closure") is defined by the compiler, and is a functor with a call operator whose signature is the one you specify when defining the lambda. Therefore, you call a lambda exactly as you would call a functor (i.e. exactly as you would call a function - or any callable object).
Thus, if you want to assign a lambda to an object, the best practice is to let the compiler deduce its type by using auto. If you do not want or cannot use auto, then you may:
Use function pointers for non-capturing lambdas (capturing lambdas are not convertible to function pointers). In the above case, thus, the following will also work:
#include <iostream>
int main()
{
void (*f)(int) = [] (int i) { std::cout << "The answer is " << i; };
f(42);
}
Use std::function (this is always possible, even if the lambda is capturing):
#include <iostream>
#include <functional>
int main()
{
std::function<void(int)> f = [] (int i)
{ std::cout << "The answer is " << i; };
f(42);
}
auto lambda = [] (int a, int b) { return a + b; };
assert(lambda(1, 2) == 3);
You don't even need a variable to hold your lambda -- you can call it directly:
std::cout << [](int n) { return n + 1 ; } (99) << std::endl ;
What is the problem with this code ? this code is giving me lots of syntax errors. Also I would like to know why functors are used in C++.
class f
{
public:
int operator(int a) {return a;}
} obj;
int main()
{
cout << obj(0) << endl;
}
You're missing an extra pair of parenthesis when declaring operator(). The name of the function is operator(), and it still needs the list of parameters after it. Thus it should look like:
int operator()(int a) {return a;}
Function objects (a.k.a. functors) like this are typically used where you'd use a pointer to a function. However, they have the advantage that they can use inheritance and they encapsulate state as well. Often, well designed class or function templates will be able to use them almost interchangeably with function pointers. However, a good optimizer can typically produce better code when a template object is used.
For a fairly sophisticated example of how you might use function objects, have a look at expression templates.
Here's a small, somewhat contrived example of how they can use inheritance:
struct unary_int_func {
virtual int operator()(int i) = 0;
};
struct negate : public unary_int_func {
int operator()(int i) {return -i;}
};
struct one_plus : public unary_int_func {
int operator()(int i) {return i+1;}
};
void show_it(unary_int_func &op, int v) {
cout << op(v) << endl;
}
In this case, we create a base class with the operator as a pure virtual function. Then we derive to concrete classes that implement it. Code such as show_it() can then use any instance of a class derived from this base. While we could just have used a pointer to a function that takes an int and returns an int, this is more typesafe. Code that uses the function pointer would accept any such function pointer, whereas this way we can define a whole new hierarchy that maps an int to an int:
struct a_different_base_class {
virtual int operator()(int i) = 0;
};
but instances of this would not be interchangeable with instances of unary_int_func.
As for state, consider a running sum function:
struct running_sum : public unary_int_func {
int total;
running_sum() : total(0) {}
int operator()(int i) {return total += i;}
};
int main()
{
running_sum s;
cout << s(1) << endl;
cout << s(2) << endl;
cout << s(3) << endl;
cout << s(4) << endl;
}
Here, the instance of running_sum keeps track of the total. It will print out 1, 3, 6 and 10. Pointers to functions have no such way of keeping state between distinct invocations. SGI's STL page on function objects has a similar example to my running sum one, but shows how you can easily apply it to a range of elements in a container.
Functors are basically functions with states. Their biggest usage is in STL and Boost libraries. For example std::sort takes a type of functor called Comparator. In this context, perhaps a function object could have been passed instead but functor offers more flexibility by means of the data members you can have and manipulate with subsequent calls to the same functor. Functors are also used to implement C++ callbacks.
As you already have figured out the issue in your operator overloading code, I would rather try to address your doubt regarding functors.
Functor is a short for 'function pointer'.
These are widely used to provide a handle to customize the behavior of an algorithm, for example the sorting algorithms in STL use functor as parameter and the user (programmer) can implement the function to tell the algorithm the result of comparison for 2 elements.
because int operator(int) is effectively equal to int int #something_missing_here#(int)
operator is a reserved keyword and not qualifier as valid function identifier/name when used alone.
I would say it is used to make compiler understand that given expression are function declaration despite the invalid identifiers used (c++ only allow alphabet and underscore as first character in naming)
A functor is an object (instance of class or struct) that typically overloads the operator(). The difference between a functor and a normal function is that because a functor is an object, it can maintain state between calls.
Because a functor is an object, rules of inheritance apply as well and you can use this to your advantage.
A functor is also useful when you use the STL. std::sort, std::for_each, etc allow you to process the contents of an entire container (arrays included). Here's an example from cplusplus.com:
// for_each example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
void myfunction (int i) {
cout << " " << i;
}
struct myclass {
void operator() (int i) {cout << " " << i;}
} myobject;
int main () {
vector<int> myvector;
myvector.push_back(10);
myvector.push_back(20);
myvector.push_back(30);
cout << "myvector contains:";
for_each (myvector.begin(), myvector.end(), myfunction);
// or:
cout << "\nmyvector contains:";
for_each (myvector.begin(), myvector.end(), myobject);
cout << endl;
return 0;
}
Try this:
class f
{
public:
int operator(int a) {return a;}
};
int main()
{
f obj;
cout<<obj(0)<<endl;
}