Where is thee callback happening in this code? - c++

class Add
{
Add(){cout<<"ctor";}
void operator()(int a ,int b){return a+b;}
}
int main()
{
Add(3,4);
}
Add is the functor.And functor can help in callback mechanism right? So where is it happening here??

And functor can help in callback mechanism right?
Yes. You could write a function template that uses a functor to perform a user-defined operation as part of whatever it's doing; for example:
template <typename Fn>
void do_stuff(Fn f, int a, int b) {
int c = f(a, b);
do_something(c);
}
and then inject your operation thusly:
do_stuff(Add(), 3, 4);
One specific use is the std::sort algorithm, which can use a user-supplied functor to compare types that don't support normal comparison operators.
So where is it happening here??
It isn't; your code doesn't compile. After fixing the return value (since it returns a value not void), you could create and invoke a function with
Add()(3,4);
But that's not particularly useful.

Related

Type signature of comparison function object

How can I use a comparison function object type in a method signature? Eg., this is all fine:
struct compInt {
bool operator() (const int a, const int b) { return a < b; }
};
set<int,compInt> s1;
// Actually this is no good, but removing it would obfuscate
// the accepted answer:
set<int> s2(compInt);
[The last one compiles but it's a function declaration, s2 turns out not to be a container].
But I want to do this:
void func (____ x)
{
set<int> s(x);
}
I do not want to do this:
template<typename C>
void func (C& c)
{
set<int> s(c);
}
And function<bool(const int,const int)> does not work. I tried making compInt::operator() virtual so I could do this:
void func (compInt& ci)
And pass in derived objects, but in fact set<int> s(ci) then fails to compile (which I'm almost grateful for, because it is a horrid hack).
set<int> s1(compInt);
This declares a function whose return type is set<int>.
set<int> s(x);
This declares a local variable of type set<int>. The comparator type is not deduced from the argument, but instead the default template argument is used. As such, compInt is not used as the comparator, so you cannot pass an instance of compInt to the constructor.
You can use:
void func (compInt x)
{
std::set<int,compInt> s(x);
I tried making compInt::operator() virtual so I could do this:
void func (compInt& ci)
Polymorphic comparator would be quite problematic. Set stores the object by value, so passing into the function through a reference would not help. You would need to use type erasure: Define a wrapper comparator that takes a polymorphic comparator as constructor argument, stores it in dynamic storage, and delegates the call operator to the stored polymorphic comparator. Then use the wrapper type as the template argument of the set.
Eeroiki got me going in the right direction. What I eventually settled on was this (note the objects to be compared actually aren't ints, and a wide range of comparators could be applied to them).
using intCompFunc = std::function<bool(const int,const int)>
struct compInt {
intCompFunc comp;
bool operator() (const int a, const int b) const {
return comp(a, b);
}
void foo (intCompfunc icf)
{
compInt ci { icf };
std::set<int,compInt> s1(ci);
}
Which means the user can pass in any kind of functor, eg. a lambda:
foo([] (const int a, const int b) { return a < b; });
My confusion stems from why it isn't this way in the first place, which I think is really a historical problem (there were no C++11 functors when the STL was written). OTOH, using a base type instead of a template parameter does introduce some runtime overhead.

What is the difference between different ways of passing a function as an argument to another function?

I have the situation where one function calls one of several possible functions. This seems like a good place to pass a function as a parameter. In this Quoara answer by Zubkov there are three ways to do this.
int g(int x(int)) { return x(1); }
int g(int (*x)(int)) { return x(1); }
int g(int (&x)(int)) { return x(1); }
...
int f(int n) { return n*2; }
g(f); // all three g's above work the same
When should which method be used? What are there differences? I prefer the simplest approach so why shouldn't the first way always be used?
For my situation, the function is only called once and I'd like to keep it simple. I have it working with pass by pointer and I just call it with g(myFunc) where myFunc is the function that gets called last.
Expanding on L.F.'s comment, it's often better to eschew function pointers entirely, and work in terms of invocable objects (things which define operator()). All of the following allow you to do that:
#include <type_traits>
// (1) unrestricted template parameter, like <algorithm> uses
template<typename Func>
int g(Func x) { return x(1); }
// (2) restricted template parameter to produce possibly better errors
template<
typename Func,
typename=std::enable_if_t<std::is_invocable_r_v<int, Func, int>>
>
int g(Func x) { return std::invoke(x, 1); }
// (3) template-less, trading a reduction in code size for runtime overhead and heap use
int g(std::function<int(int)> x) { return x(1); }
Importantly, all of these can be used on lambda functions with captures, unlike any of your options:
int y = 2;
int ret = g([y](int v) {
return y + v;
});

Is it possible to pass a function as a parameter in C++?

Is there any way to pass a function as a parameter in C++, like the way that functions can be passed as parameters in C? I know that it's possible to pass a function as a parameter in C using function pointers, and I want to know whether the same is possible in C++.
You can do it like in C. But you can also do it the C++ way (C++11, to be exact):
// This function takes a function as an argument, which has no
// arguments and returns void.
void foo(std::function<void()> func)
{
// Call the function.
func();
}
You can pass a normal function to foo()
void myFunc();
// ...
foo(myFunc);
but you can also pass a lambda expression. For example:
foo([](){ /* code here */ });
You can also pass a function object (an object that overloads the () operator.) In general, you can pass anything that can be called with the () operator.
If you instead use the C way, then the only thing you can pass are normal function pointers.
It's possible in C++ just as in C to pass functions as parameters but with a few differences: we can use function references instead of pointers, templates types in addition to variadic template arguments. For example:
Function references:
In C, we don't have the ability to pass objects by reference. This however is possible in C++:
void f( void (&)() ) {}
f( h );
The difference between references are pointers is subtle, but important. For instance, we can't pass NULL or 0 to a function expecting a reference; the argument must be satisfied with its type immediately. References are usually preferred in most cases over pointers.
Templates:
Templates allow us to generically pass functions with variable type attributes as parameters:
template <class T, class U>
void f( T (&)( U ) ) {}
The above signature accepts a function with any return type or parameter list (the only setback is that the function must take one argument).
In addition to this feature, we can also utilize varaidic templates to allow functions with variable-length parameter lists:
template <class T, class ...U>
void f( T (&)( U... ) ) {}
int h(int, int) { .. }
bool g(std::string) { .. }
f( h );
f( g );
The implementation of f can also use perfect forwarding if we are using U&&:
template <class T, class ...U>
void f( T (&fun)( U&&...) ) {
// ...
fun( std::forward<U>(u)... );
}
There are also lambdas which are commonly bound with std::function<T(U)>.
Yes, function pointers work exactly the same way in C++ as in C.
Yes, like this:
#include <stdio.h>
typedef void (*my_func)(int);
void do_something (my_func f)
{
f (10);
}
void square (int j)
{
printf ("squared: %d\n", j * j);
}
void cube (int j)
{
printf ("cubed: %d\n", j * j * j);
}
int main (int argc, char *argv[])
{
do_something (square);
do_something (cube);
}
The output is:
squared: 100
cubed: 1000
The typedef is to make the syntax for do_something() a bit more readable.
I would like to point out that, since you are using C++ already, it is much easier ways to achieve the same with virtual functions.
Yes, it is possible.
I found a working example program (which can be tested and edited online, and illustrates the concept well): http://ideone.com/6kSTrp#view_edit_box
//this was taken from http://www.cprogramming.com/tutorial/function-pointers.html
#include <stdio.h>
void my_int_func(int x)
{
printf( "%d\n", x );
}
int main()
{
void (*foo)(int); //pointer to an int function
foo = &my_int_func;
/* call my_int_func (note that you do not need to write (*foo)(2) ) */
foo( 2 );
/* but if you want to, you may */
(*foo)( 2 );
return 0;
}

Template filled by an operator

Can you use templates (or the like) in C++ to specify which operation is done in a function?
I don't know how to explain it more clearly, so I'll show you how it could be (but isn't) done in code:
template <operator OPERATION> int getMaxOrMin(int a, int b) {
return a OPERATION b ? a : b;
}
where finding the maximum or the minimum of a or b would be (this is where my pseudo-syntax gets a little confusing, bear with me):
int max = getMaxOrMin< > > (a, b);
int min = getMaxOrMin< < > (a, b);
I know that's not how to do it at all (because it doesn't even syntactically make sense), but I hope that clarifies the type of thing I want to do.
The reason behind me wondering this is I'm making a PriorityQueue implementation, and it would be nice to easily switch between the backing being a max-heap or a min-heap on the fly without copying and pasting code to make two different classes.
I know I could do it with a macro, but the only way I'd know how to do that would give me either a max-heap or a min-heap, but not both in the same compilation. I'm probably overlooking a way, though.
Do what std::map and friends do: Take a comparison function/functor as your template parameter. See std::less and std::greater.
Do remember that the standard library already has a well developed and debugged priority queue that you can use with an arbitrary comparison function.
Yes but you need to define it like a functor:
template <typename OPERATION>
int getMaxOrMin(int a, int b)
{
OPERATION operation;
return operation(a, b) ? a : b;
}
Now you can use it like this:
struct myLess
{
bool operator()(int a,int b) const { return a < b; }
}
struct myGreat
{
bool operator()(int a,int b) const { return a > b; }
}
void code()
{
int x = getMaxOrMin<myLess>(5,6);
int y = getMaxOrMin<myGreat>(5,6);
}
That seems like a lot of work. But there are a lot of predefined functors in the standard. On this page scroll down to "6: Function Objects".
For your situation there is:
std::less
std::greater
So the code becomes:
template <typename OPERATION>
int getMaxOrMin(int a, int b)
{
OPERATION operation;
return operation(a, b) ? a : b;
}
void codeTry2()
{
int x = getMaxOrMin<std::less<int> >(5,6);
int y = getMaxOrMin<std::greater<int> >(5,6);
}

How can it be useful to overload the "function call" operator?

I recently discovered that in C++ you can overload the "function call" operator, in a strange way in which you have to write two pair of parenthesis to do so:
class A {
int n;
public:
void operator ()() const;
};
And then use it this way:
A a;
a();
When is this useful?
This can be used to create "functors", objects that act like functions:
class Multiplier {
public:
Multiplier(int m): multiplier(m) {}
int operator()(int x) { return multiplier * x; }
private:
int multiplier;
};
Multiplier m(5);
cout << m(4) << endl;
The above prints 20. The Wikipedia article linked above gives more substantial examples.
There's little more than a syntactic gain in using operator() until you start using templates. But when using templates you can treat real functions and functors (classes acting as functions) the same way.
class scaled_sine
{
explicit scaled_sine( float _m ) : m(_m) {}
float operator()(float x) const { return sin(m*x); }
float m;
};
template<typename T>
float evaluate_at( float x, const T& fn )
{
return fn(x);
}
evaluate_at( 1.0, cos );
evaluate_at( 1.0, scaled_sine(3.0) );
A algorithm implemented using a template doesn't care whether the thing being called is a function or a functor, it cares about the syntax. Either standard ones (e.g. for_each()) or your own. And functors can have state, and do all kinds of things when they are called. Functions can only have state with a static local variable, or global variables.
If you're making a class that encapsulates a function pointer, this might make the usage more obvious.
The compiler can also inline the functor and the function call. It cannot inline a function pointer, however. This way, using the function call operator can significantly improve performance when it is used for example with the standard C++ libary algorithms.
For example for implementing generators:
// generator
struct Generator {
int c = 0;
virtual int operator()() {
return c++;
}
};
int sum(int n) {
Generator g;
int res = 0;
for( int i = 0; i < n; i++ ) {
res += g();
}
return res;
}
I see potential to yet one exotic use:
Suppose you have object of unknown type and have to declare another variable of same type, like this:
auto c=decltype(a*b)(123);
When such pattern used extensively, decltype become very annoying.
This case can occur when using some smart type system that automatically invent type of result of functions and operators based on types of arguments.
Now, if each specialization of each type of that type system equipped with
magic definition of operator() like this:
template<????> class Num<???>{
//specific implementation here
constexpr auto operator()(auto...p){return Num(p...);}
}
decltype() no more needed, you can write simply:
auto c=(a*b)(123);
Because operator() of object redirects to constructor of its own type.