c++: std::vector of std::function with arbitrary signatures - c++

Is it possible to create an std::vector that can hold an std::function with any signature?
(The function arguments would all be pre-bound.)
I tried std::vector<std::function<void()> >, since if I only have one std::function of that type I can bind any function to it.
This does not seem to work inside a vector: if I try to add a function with std::bind to the vector that has a signature other than void(), I get:
No matching member function for call to 'push_back'
Is there a way to do this?
Edit:
I just remembered that std::function<void()> does allow you to bind any function that returns void as long as the arguments are pre-bound with std::bind, it does not allow you to bind any signature though, but for my purposes it's generic enough, so the following works:
class A
{
public:
void test(int _a){ return 0; };
};
A a;
std::vector<std::function<void()> > funcArray;
funcArray.push_back(std::bind(&A::test, std::ref(a), 0));

This should work:
#include <iostream>
#include <functional>
#include <vector>
void hello() { std::cout << "Hello\n"; }
void hello2(const char * name) { std::cout << "Hello " << name << '\n'; }
int main()
{
std::vector<std::function<void()>> v;
v.push_back(hello);
v.push_back(std::bind(hello2, "tim"));
v[0]();
v[1]();
}
How are you doing it?

Is it possible to create an std::vector that can hold an std::function with any signature? (The function arguments would all be pre-bound.)
So you're wondering if you can use a vector to hold objects of different types except that you've wrapped them all up in a single type?
Yes, you can store a bunch of items that all have the same type in a vector.
Or maybe you're trying to ask "How do I wrap callable objects such that they'll have the type I need?"
bind can handle the special case where you only need to remove or reorder parameters in order to get something convertible to the common type. In order to handle the general case where you may need choose the return type, add parameters, etc., you simply have to write new functions. Lambda's can make it easy to do that inline:
std::vector<std::function<common_signature> F;
double foo(std::string);
// for a common signature of void()
F.push_back([]{ foo("hello"); });
int bar(void);
// for a common signature of int (int)
F.push_back( [](int i) { return bar() + i; });
int baz(void);
// for a common signature of std::complex<double> (void)
F.push_back( []() -> std::complex<double> { return {0,baz()}; });

Related

Passing a math function as method's input parameter C++

I am trying to write a general integral function and I would like to implement it in such a way so that it can accept any mathematical function. That is, I would like to pass the math function as an input parameter. In pseudo-code: simpson_int(x*x). I've heard of the function template in <functional> but I don't really have experience with templates in C++.
There are some solutions that comes in my mind (and this is my approach at the problem, for sure there are more solution, and maybe what I'm pointing out is not the best), that consider the fact that you need to call the argument function more than once in the Simpson implementation (thus you need a "callable" argument):
Function pointer
Function pointers (more C than C++), where you declare with two arguments: the first one will be the pointer to a function with the specified types, while the second is the argument for your function. Lets
make an example:
#include <iostream>
double power2(double x) {
return x * x;
}
double simspon(double (*f)(double), double x) {
return f(x);
}
int main() {
std::cout << simspon(power2, 2);
return 0;
}
In this case I have used no templates for reaching the result. But this will not take any function as first argument, but only a function that has as argument a double and returns a double.
I think that most of c++ programmer will suggest you to avoid this method.
Function pointer and templates
So you maybe want to expand the previous example using templates and making it more general. It is quite simple to redefine the function
to accept a template (an abstract type) that you actually specify only when you use it in your code:
#include <iostream>
double power2(double x) {
return x * x;
}
int power2int(int x) {
return x * x;
}
template <class T, class P>
P simspon(T (*f)(P), P x) {
return f(x);
}
int main() {
std::cout << simspon<double, double>(power2, 2.0);
std::cout << simspon<int, int>(power2int, 2);
return 0;
}
T and P are two templates: the first one is used for describing the returned value of the function pointer, while the second specify the argument of the function pointer, and the returned value of simpson.So when you are writing template <class T, classP> you are actually informing the compiler that that you are using T and P as placeholder for different type. You will actually declare the type that you want later on, when you will call the function in the main. This is not good code but I'm building the path to understand templates. Also, you specify the type of your argument function when you actually call simpson, with the < >.
(Disclaimer: you should consider to use template <typename T ...> instead of class. But I'm used with the old class and there are situation in which typename cannot be used, there are a lot of questions on SO that dive into this.)
Using std::function
Instead of using a function pointer as argument you may want to create a variable that stores your function to be passed as argument of simpson. This bring several advantages, because they are actually an object inside your code that have some predictable behavior in some unwanted circumstances (for example, in case of a null function pointer you have to check the pointer itself and handle it, in case of std::function if there is no callable pointer it throws std::bad_function_call error)
Here an example, and it uses again templates, as before:
#include <iostream>
#include <functional>
double power2(double x) {
return x * x;
}
int power2int(int x) {
return x * x;
}
template <class T, class P>
P simspon(std::function<T(P)> f, P x) {
return f(x);
}
int main() {
std::function<double(double)> p_power2 = power2;
std::cout << simspon<double, double>(p_power2, 2.0);
std::function<double(double)> p_power2int = power2int;
std::cout << simspon<int, int>(power2int, 2);
return 0;
}
Using lambdas
lambdas are closure and in your case (if you can use the standard C++14) can be used alongside the auto keyword to achieve quite a general behavior, without the explicit use of templates. The closure are also able to capture part/the whole context, check the reference for this.
Let's see an example, in which I create two lambdas that receive different arguments and a simpson function that is quite general (actually it is not, is the compiler that defines different functions with respect to the call that you do).
#include <iostream>
auto lambda = [](auto x) { return x * x ; };
auto lambda_2 = [] (int x) { return x + 10; };
auto simpson(auto f, auto x) {
return f(x);
}
int main() {
std::cout << simpson(lambda, 2.0);
std::cout << simpson(lambda_2, 1);
return 0;
}
You need to compile it with the -std=c++14 flag. There are tons of advise that comes in my mind to suggest you to avoid to implement your code in this way, remember that it has only some illustrative purposes (I've more than exaggerated with the auto keyword).
Function objects (the Problem class)
Maybe an improvement for your case is to write a general class for the mathematical functions to integrate and pass the object to your function. This bring several advantages: you may want to save some of the integrative result inside your function or even write the stream operator to pretty print your problem. This is the solution employed typically by mathematical libraries.
In this extremely simple case, we have a class that is a problem. When you create a new instance for this class, a std::function is passed to the constructor and stored inside the class. The instance of the class is the argument for your simpson:
#include <iostream>
#include <functional>
template <class T, class P>
class Problem {
public:
// Attributes
std::function<T(P)> _f;
// Constructor
Problem(std::function<T(P)> f) : _f(f) {};
// Making the object callable
P operator()(P x) { return _f(x); }
};
template <class T, class P>
P simspon(Problem<T, P> p, P x) {
return p(x);
}
int main() {
Problem<double, double> prb([](double x) { return x * x; });
std::cout << simspon<double, double>(prb, 2);
return 0;
}
Use std::function, like this for example:
#include <iostream> // std::cout
#include <functional> // std::function
int main()
{
std::function<double(double)> simpson_int =([](double x) { return x * x; };
std::cout << "simpson_int(4): " << simpson_int(4) << '\n';
return 0;
}
which outputs:
simpson_int(4): 16

Passing a pointer to a member function as argument for a void* function

I have the following function:
void PerformAction(void(*pf_action)());
and the following class:
class A
{
public:
void DoSomething();
}
I want to be able to do this:
int main()
{
A a;
PerformAction(&(a.DoSomething);
return 0;
}
I have seen many answers that say that the function signature should be:
void PerformAction(void(A::*)());
This is not what I want.
I want to able to pass it any function/method that receives no parameters and returns void. Not just member methods of A or just global functions.
Is this possible in C++?
Plain function pointers and member function pointers are different things.
Member functions take a hidden this parameter, whereas plain functions do not. To call a member function through a pointer an object is required to initialize that this parameter.
Hence, you cannot convert a pointer to a non-static member function to a plain function pointer and call through it without passing in an object.
I want to able to pass it any function/method that receives no parameters and returns void. Not just member methods of A or just global functions.
Is this possible in C++?
Yes, it is possible, but you need to use a more flexible type. The way to achieve this is to specify the PerformAction function with a different type. You want to use a type that is callable with zero arguments and returns void, std::function<void ()>. For example change the PerformAction function to be: void PerformAction(std::function<void ()> fn);. This version will allow you to accept anything that's callable with zero arguments and returns void, see the following code for an example.
Example Code
#include <functional>
#include <iostream>
class Foo
{
public:
void bar() { std::cout << "Member function: Foo::bar()\n"; }
};
void bar()
{
std::cout << "Free function: bar()\n";
}
class Functor
{
public:
void operator()() { std::cout << "Functor object\n"; }
};
auto lambda = []() { std::cout << "Lambda expression\n"; };
void doSomething(std::function<void ()> fn)
{
fn();
}
int main()
{
doSomething(bar);
doSomething(Functor());
doSomething(lambda);
Foo foo;
doSomething(std::bind(&Foo::bar, &foo));
return 0;
}
Live Example
Example Output
Free function: bar()
Functor object
Lambda expression
Member function: Foo::bar()

how to decide if bind() need parenthesis in the parameter

I am using bind() to bind a function and its parameters together. I used the build-in functor multiplies and I also tried a function I wrote myself AddVal2(). The following is a correct version of the code. But I really don't understand why std::bind(std::multiplies<int>(),std::placeholders::_1,10) has to include () with multiplies<int>, while bind(AddVal2,std::placeholders::_1,10) write AddVal2 instead of AddVal2(). Thank you.
#include<iostream>
#include<vector>
#include<algorithm>
void AddVal2(int x, int y)
{ std::cout << x+y << std::endl;}
int main()
{
std::vector<int> vec = {1,2,3,4,5};
std::vector<int> vec_result;
std::transform(vec.begin(),vec.begin()+2,std::back_inserter(vec_result),std::bind(std::multiplies<int>(),std::placeholders::_1,10));
for (std::vector<int>::iterator itr = vec_result.begin(); itr !=vec_result.end();++itr){std::cout << *itr << std::endl;}
for_each(vec.begin(),vec.end(),std::bind(AddVal2,std::placeholders::_1,10));
}
That's simple: std::multiplies<T> is a class template which defines a
function call operator. It looks something like this:
template <typename T>
struct multiplies {
// some typedefs are here, too
T operator()(T const& a0, T const& a1) const { return a0 * a1; }
};
To create such an object, you'll use a default constructor, i.e., std::multiplies<T>().
On the other hand AddVal2 is a function. To get a function object from a normal function you just mention the function and it'll decay into a function pointer. Alternatively you can also use &AddVal2 to explicitly obtain a function pointer (for member functions you have to explicitly take the address).

Is there a use case for std::function that is not covered by function pointers, or is it just syntactic sugar? [duplicate]

This question already has answers here:
Why do we use std::function in C++ rather than the original C function pointer? [duplicate]
(3 answers)
Closed 9 years ago.
The notation for std::function is quite nice when compared to function pointers. However, other than that, I can't find a use case where it couldn't be replaced by pointers. So is it just syntactic sugar for function pointers?
std::function<> gives you the possibility of encapsulating any type of callable object, which is something function pointers cannot do (although it is true that non-capturing lambdas can be converted to function pointers).
To give you an idea of the kind of flexibility it allows you to achieve:
#include <functional>
#include <iostream>
#include <vector>
// A functor... (could even have state!)
struct X
{
void operator () () { std::cout << "Functor!" << std::endl; }
};
// A regular function...
void bar()
{
std::cout << "Function" << std::endl;
}
// A regular function with one argument that will be bound...
void foo(int x)
{
std::cout << "Bound Function " << x << "!" << std::endl;
}
int main()
{
// Heterogenous collection of callable objects
std::vector<std::function<void()>> functions;
// Fill in the container...
functions.push_back(X());
functions.push_back(bar);
functions.push_back(std::bind(foo, 42));
// And a add a lambda defined in-place as well...
functions.push_back([] () { std::cout << "Lambda!" << std::endl; });
// Now call them all!
for (auto& f : functions)
{
f(); // Same interface for all kinds of callable object...
}
}
As usual, see a live example here. Among other things, this allows you to realize the Command Pattern.
std::function is designed to represent any kind of callable object. There are plenty of callable objects that cannot be represented in any way by a function pointer.
A functor:
struct foo {
bool operator()(int x) { return x > 5; }
};
bool (*f1)(int) = foo(); // Error
std::function<bool(int)> f2 = foo(); // Okay
You cannot create an instance of foo and store it in a bool(*)(int) function pointer.
A lambda with a lambda-capture:
bool (*f1)(int) = [&](int x) { return x > y; }; // Error
std::function<bool(int)> f2 = [&](int x) { return x > y; }; // Okay
However, a lambda without a capture can be converted to a function pointer:
The closure type for a lambda-expression with no lambda-capture has a public non-virtual non-explicit const conversion function to pointer to function having the same parameter and return types as the closure type’s function call operator. The value returned by this conversion function shall be the address of a function that, when invoked, has the same effect as invoking the closure type’s function call operator.
Implementation-defined callable return values:
bool foo(int x, int y) { return x > y; };
bool (*f1)(int) = std::bind(&foo, std::placeholders::_1, 5); // Error (probably)
std::function<bool(int)> f2 = std::bind(&foo, std::placeholders::_1, 5); // Okay
std::bind's return value is an implementation-defined callable object. Only how that object may be used is specified by the standard, not its type.

Parameter/storage type for a C++11 lambda

In C++11, how do you declare a function that takes a lambda expression as an argument? I can find plenty of resources online for declaring lambdas or taking them as template parameters, but what I'd really like to do is be able to make use of lambdas as easy-to-declare callback handlers, similar to what's made possible by closures in JavaScript and code blocks in Objective-C.
Essentially, the classic C++ construct I want to replace with a lambda is something like:
class MyCallback {
public:
virtual ~MyCallback() {}
virtual void operator(int arg) = 0;
};
void registerCallback(const std::shared_ptr<MyCallback> &);
void foo(void) {
int a, b, c;
class LocalCallback: public MyCallback {
int a, b, c;
public:
LocalCallback(int a, int b, int c): a(a), b(b), c(c) {}
void operator(int arg) { std::cout << (a+b+c)*arg << std::endl; }
};
registerCallback(std::shared_ptr<MyCallback>(new LocalCallback(a,b,c)));
}
which would be simplified into:
void registerCallback(/* WHAT GOES HERE? */);
void foo(void) {
int a, b, c;
registerCallback([=](int arg){std::cout << (a+b+c)*arg << std::endl; })
}
So, what goes where I have written /* WHAT GOES HERE? */?
EDIT: This is for the purpose of storing a callback to be called back later, rather than for it being immediately consumed and called.
Usually const std::function<void(int)> & or std::function<void(int)>.
I'm not sure what the verdict is on whether std::function should be passed by const reference or by value. Probably by value is fine, especially since you're going to copy it anyway to store.
In case it isn't clear in the middle of all that syntax, void(int) is a function type, and std::function<T> means approximately, "a functor with the same signature as functions of type T".
Lambdas themselves have anonymous types. There is no way to name the type of your lambda expression, and the types of different lambda expressions with the same signature are different:
auto foo = [=](int arg){std::cout << (a+b+c)*arg << std::endl; };
auto bar = [=](int arg){std::cout << (a+b+c)*arg << std::endl; };
// foo and bar have different types, accessible as decltype(foo), decltype(bar)
Hence the need for std::function, which basically is a type-erasing wrapper to gather together different functors with the same signature into a common type. It's the bridge between static polymorphism with templates, and the dynamic polymorphism you need if you want to register a callback, store it for later, and then call it without having "remembered" the original type.
void registerCallback(const std::function<void(int)>& callback);
Consider using a function template. There are a variety of good reasons to, such as better behaviour when overloading (overloading on std::function is painful):
template<typename Functor>
void registerCallback(Functor&& functor);
(You can also accept the parameter as Functor functor, that's not too important.)
If the code needs to e.g. store the functor later on, then that will likely be held inside an std::function. Where you want to avoid std::function is in function parameters.