лямбда — удалить дубликат подписи типа в переполнении стека

У меня есть следующий фрагмент кода в 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) { /* ... */ }
    

    Я сомневаюсь, что возможно ли реализовать вторую версию.

Кроме того, я очень надеюсь, что макрос будет хорошо работать с любым количеством аргументов. Благодарю.

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]