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()}; });