Reputation: 41
I need to create a vector that will store void functions with different number of parameters. I used variadic templates for this, but it doesn't work.
#include <iostream>
#include <functional>
template<class...Types>
using MyFun = std::function<void(Types...)>;
std::vector<MyFun<>> operators;
template<class Lambda>
void addOperator(Lambda lambda)
{
operators.emplace_back(lambda);
}
int main()
{
auto f1 = [](int a, int b){std::cout<<a+b;};
auto f2 = [](double a, double b){std::cout<<a+b;};
addOperator(f1);
addOperator(f2);
return 0;
}
Can you help me?
Upvotes: 2
Views: 733
Reputation: 14603
You need anyfunc, which is an upgraded std::any
, that allows invocation. You can just do:
std::vector<gnr::anyfunc> v;
Just like you would with a std::any
, but you need to remember the exact function signature of the functor you stored, though this can be hacked around, if you write your own anyfunc
. Anyway, here's an example.
std::vector<gnr::anyfunc<>> v{
[&](){ std::cout << "yay" << std::endl; },
[&](int const i) { std::cout << i << std::endl; }
};
v[0]();
v[1](1);
But this is just one example. You can even store coroutines in lists without any problems.
Upvotes: 0
Reputation: 29985
Assuming you have a small number of possible types, here's an example:
#include <stdio.h>
#include <variant>
#include <vector>
// this helper is from https://en.cppreference.com/w/cpp/utility/variant/visit
template <class... Ts>
struct overloaded : Ts... {
using Ts::operator()...;
};
template <class... Ts>
overloaded(Ts...) -> overloaded<Ts...>;
int main() {
using T1 = void (*)(int, int);
using T2 = void (*)(double, double);
T1 const f1 = [](int a, int b) { printf("int add: %d\n", a + b); };
T2 const f2 = [](double a, double b) { printf("double add: %f\n", a + b); };
std::vector<std::variant<T1, T2>> vec{f1, f2};
// add more elements if needed
for (auto const& f : vec) {
// example usage
std::visit(overloaded([](T1 const& f) { f(1, 2); },
[](T2 const& f) { f(1.5, 2.3); }), f);
}
}
Upvotes: 4