【发布时间】:2015-02-06 19:42:53
【问题描述】:
我有几个自定义类型将用作函数的不同参数:
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(为简单起见,此处未实现)并用 A 调用 H。
我有类似的转换器 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 次,将得到获取类型为“E”的参数的函子,最后用参数“A”调用内部处理程序:
auto inner_handler = [] (A) -> bool { return false; };
auto f = foo (foo (foo (foo ( inner_handler ))));
f (E {});
我想要的是实现 call_until 函数,该函数将递归调用“foo”重载,直到结果函子的参数类型变为 T。
假设从 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);
}
但是我遇到了编译错误,并且有点卡在这一点上。我需要一些想法来实现这一点。
【问题讨论】:
-
尝试使用
->来表示“从左侧获取参数,并返回右侧”,因为这匹配更传统的函数符号。所以有一个过载foo:H:A->bool->G:B->bool。为了让你的代码更干净,你可以用result_of_t替换result_of吗?如果你的编译器没有,写一个template<class Sig>using result_of_t=typename std::result_of<Sig>::type;。噪音越小越好。