我目前正在尝试为 std::functions 定义一个通用乘法运算符。我想使用多个可变参数模板来做到这一点。部分专业化如下所示:
template <typename... _Type> using op_Type = typename std::function<u64(u64, _Type...)>;
inline auto operator*(const op_Type<>& f, const op_Type<>& g) -> op_Type<> {
return [f, g](u64 num) {
return f(g(num));
};
}
template <typename _Ty1, typename _Ty2>
inline auto operator*(const op_Type<_Ty1>& f, const typename op_Type<_Ty2>& g)
-> op_Type<_Ty1, _Ty2> {
return [f, g](u64 num, _Ty1 arg1, _Ty2 arg2) {
return f(g(num, arg2), arg1);
};
}
template <typename _Tyf1, typename _Tyf2, typename _Tyg1, typename _Tyg2>
inline auto operator*(const op_Type<_Tyf1, _Tyf2>& f,
const typename op_Type<_Tyg1, _Tyg2>& g)
-> op_Type<_Tyf1, _Tyf2, _Tyg1, _Tyg2> {
return [f, g](u64 num, _Tyf1 argF1, _Tyf2 argF2, _Tyg1 argG1, _Tyg2 argG2) {
return f(g(num, argG1, argG2), argF1, argF2);
};
}
但我需要的是任何通用 std::functions 采用 u64 值和任意数量的其他参数的相同行为,应该如下所示:
template <typename... _Ty1, template <typename...> class op1
, typename... _Ty2, template <typename...> class op2
, typename... _RetTy, template<typename...> class opRet>
inline auto operator*(const op1<_Ty1...>& f, const op2<_Ty2...> g) -> opRet<_RetTy...> {
const int size1 = sizeof...(_Ty1);
const int size2 = sizeof...(_Ty2);
return [f, g](u64 num, _Ty1 args1..., _Ty2 args2...) {
auto tmp = g(num, std::forward<_Ty1>(args1)...);
return f(tmp, std::forward<_Ty2>(args2)...);
};
}
我也想删除添加的类模板,但可能无法使用多个可变参数模板,因为编译器不知道可变参数模板何时结束,对吧?我想一个好的解决方法是拆分参数包,这样:
template <typename... _Ty1, , typename... _Ty2>
inline auto operator*(const op_type<_Ty1...>& f, const op_type<_Ty2...> g) -> opRet<_Ty1...,_Ty2...> {
const int size1 = sizeof...(_Ty1);
const int size2 = sizeof...(_Ty2);
return [f, g](u64 num, variadic template args...) {
auto tmp = g(num, split_args(args, 0, size1 - 1));
return f(tmp, split_args(args, remaining_arguments);
};
}
其中 split_args 返回输入索引之间的参数,但我不确定如何实现它,有什么想法吗?我找到了这样的解决方案: http ://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0535r0.html 但我不确定是否有可用的开源代码
编辑: 总之,我需要一个看起来像这样的函数:
template <typename... _Ty1, typename... _Ty2>
inline auto operator*(const op_type<_Ty1...>& f, const op_type<_Ty2...> g) -> op_type<_Ty1...,_Ty2...> {
return [f, g](u64 num, _Ty1 args1..., _Ty2 args2...) {
auto tmp = g(num, std::forward<_Ty1>(args1)...);
return f(tmp, std::forward<_Ty2>(args2)...);
};
}
EDIT2:用法:假设我有两个功能:
auto f(u64 num, int i, int j) -> u64{
return num + (i - j)^i;
}
和
auto g(u64 num, double x){
return num - int(num / x);
}
那么乘法运算符 h = f*g 应该将 h 返回为:
auto h(u64 num, int i, int j, double x) -> u64{
num + (i - j)^i - int(num / x);
}