У меня есть несколько пользовательских типов, которые будут использоваться в качестве отдельных аргументов для функций:рекурсивная вызов перегруженных C++ функции
struct A {};
struct B {};
struct C {};
struct D {};
struct E {};
Есть также целый ряд функций, которые возвращают функтор обертки:
template <typename H>
auto foo (H h,
enable_if_t<is_same<typename result_of<H(A)>::type, bool>::value>* = 0)
{
return [h] (B x) { return h (A {}); };
}
Это вещь преобразует функтор H (A) в функтор G (B), который преобразует входной аргумент B-> A (не реализованный здесь для простоты) и вызывает H с A.
У меня есть аналогичный con vertors C-> B, D> C, E-> D:
template <typename H>
auto foo (H h,
enable_if_t<is_same<typename result_of<H(B)>::type, bool>::value>* = 0)
{
return [h] (C x) { return h (B {}); };
}
template <typename H>
auto foo (H h,
enable_if_t<is_same<typename result_of<H(C)>::type, bool>::value>* = 0)
{
return [h] (D x) { return h (C {}); };
}
template <typename H>
auto foo (H h,
enable_if_t<is_same<typename result_of<H(D)>::type, bool>::value>* = 0)
{
return [h] (E x) { return h (D {}); };
}
Теперь я могу назвать Foo 4 раза и получить функтор, который получает аргумент типа «Е», и, наконец, вызывает внутренний обработчик с аргумент «A»:
auto inner_handler = [] (A) -> bool { return false; };
auto f = foo (foo (foo (foo (inner_handler))));
f (E {});
То, что я хочу, чтобы реализовать функцию call_until, которая будет вызывать «Foo» перегружает рекурсивно до тех пор аргумент типа результирующих функтор стал Т.
Скажем, путь конвертеров от A к E всегда существует и является одним. Другими словами, я хотел бы Выражение
auto f = call_until<E> (inner_handler);
работу именно так, как
auto f = foo (foo (foo (foo (inner_handler))));
Я, начиная с чем-то вроде:
template <typename Stop, typename Handler, typename Result>
struct call_until_helper
{
Handler handler_;
call_until_helper (Handler h) : handler (h) {}
};
template <typename Stop, typename Handler>
call_until_helper<Stop, Handler,
typename boost::function_traits<Handler>::result_type>
call_until (Handler handler)
{
return call_until_helper<Stop, Handler,
typename boost::function_traits<Handler>::result_type> (handler);
}
Но я получил ошибки компиляции и своего рода застрял эта точка. Мне нужно несколько идей, как это реализовать.
Кода на сайте: http://ideone.com/ZRFxnw
Попробуйте использовать '-> 'означает«принимает аргументы с левой стороны, и возвращает правую сторону», поскольку это соответствует более обычное функциональное обозначение. Таким образом, существует перегрузка 'foo:' 'H: A-> bool'' ->' 'G: B-> bool'. Чтобы сделать ваш код более чистым, можете ли вы заменить 'result_of' на' result_of_t'? Если ваш компилятор не имеет его, напишите один 'template, используя result_of_t = typename std :: result_of :: type;'. Меньше шума. –
Yakk