У меня есть следующий фрагмент кода в C ++ 14:
#include <iostream>
#include <functional>
using namespace std;
template <typename T> using Func = function<T>;
template <typename T> using Epct = Func<void (T)>;
template <typename... Ts> using PartGen = Func<void (Ts...)>;
template <typename T> struct RevEpct : public RevEpct<decltype(&T::operator())> {};
template <typename T, typename C> struct RevEpct<void (C::*)(T) const> {
using Type = T;
};
template <typename F> auto foo(F func) { // F: Epct<Epct<PartGen<int, double>>>
using T = typename RevEpct<F>::Type; // T: Epct<PartGen<int, double>>
using U = typename RevEpct<T>::Type; // U: PartGen<int, double>
return [=] (auto ...vs) {
func([=] (U u) {
u(vs...);
});
};
}
int main() {
foo([] (Epct<PartGen<int, double>> k) {
k([] (int x, double y) {
// do something here
cout << x << " " << y << endl;
});
})(42, 42.5);
}
Каждый раз звоню foo
, Я должен написать подпись того же типа (в этом случае <int, double>
) дважды. По какой-то причине я не может просто написать функцию-обертку, которая принимает (int, double) -> void
лямбда как аргумент. Таким образом, я ищу решение любым из этих двух способов:
foo
функция? Я попытался заменить аргумент внешней лямбда auto k
но это не сработает.Есть ли в любом случае написать макрос, который может быть использован следующим образом:
FOO(k, [] (int x, double y) { /* ... */ })
или вот так:
FOO(k, int, x, double, y) { /* ... */ }
Я сомневаюсь, что возможно ли реализовать вторую версию.
Кроме того, я очень надеюсь, что макрос будет хорошо работать с любым количеством аргументов. Благодарю.
Задача ещё не решена.
Других решений пока нет …