У меня есть код, который принимает функцию и выполняет ее на основе сигнатуры функции, как показано ниже:
template <int Num>
struct Value {
int value[Num];
};
struct Executor {
template <int N>
void do_exec(std::vector<Value<N>>& n, void (&func) (Value<N>&)) {
for (auto& item : n)
func(item);
}
template <int N>
void do_exec(std::vector<Value<N>>& n, void (&func) (Value<N>&, int)) {
for (int i = 0; i != n.size(); i++)
func(n[i], i);
}
};
когда пользователь передает одну из следующих функций, Executor
запускает do_exec()
который соответствует его сигнатурам.
template <int N>
void f1(Value<N>& item)
{
for (auto& i : item.value) {
i = 123;
}
}
template <int N>
void f2(Value<N>& item, int d)
{
for (auto& i : item.value) {
i = d;
}
}
int main()
{
Executor exec;
std::vector<Value<3>> vec(10);
exec.do_exec(vec, f1);
}
Я хотел бы расширить этот код, чтобы он мог принимать лямбда-функции, поскольку в реальном коде почти все агенты будут вызывать это с помощью лямбда-выражений GENERI C.
Я попытался заменить функторы на std::function
, но это не удалось, так как лямбда - это не std::function
и вывода типа на самом деле не было.
затем я попытался взять два аргумента шаблона и SFINAE из той, которая не соответствует подписи, как показано ниже:
template <typename Fn, typename T, typename = void>
struct HasIndex : std::false_type {};
template <typename Fn, typename T>
struct HasIndex<Fn, T, std::void_t<std::invoke_result_t<Fn, T&, int>>> : std::true_type {};
struct Executor {
template <int N, typename Fn, std::enable_if_t<!HasIndex<Fn, Value<N>>::value, int> = 1>
void do_exec(std::vector<Value<N>>& n, Fn func) {
for (auto& item : n)
func(item);
}
template <int N, typename Fn, std::enable_if_t<HasIndex<Fn, Value<N>>::value, int> = 1>
void do_exec(std::vector<Value<N>>& n, Fn func) {
for (int i = 0; i != n.size(); i++)
func(n[i], i);
}
};
это тоже не сработало, поскольку функции, которые выполняет исполнитель, ВСЕГДА являются шаблонными функциями (GENERI C Lambda). Я не знаю точно, как подойти к этой проблеме, любая помощь приветствуется.
решение c ++ 14, пожалуйста (я знаю, что invoke_result - это c ++ 17)
https://godbolt.org/z/W7z3Mv