C++ 如何对参数化模板函数进行类型推断
您不能直接执行此操作,但可以将函数转换为函数对象:C++ 如何对参数化模板函数进行类型推断,c++,templates,template-argument-deduction,C++,Templates,Template Argument Deduction,您不能直接执行此操作,但可以将函数转换为函数对象: CallFuncs(1,2, Add, Mul); 或显式类型规范: CallFuncs(1., 2., Add{}, Mul{}); 如果T是void(例如,在std::plus{})中,plus::operator()推断参数和返回类型。典型的情况如下(稍作简化): template struct plus{ 模板 constexpr自动运算符()(Tp&t,Up&u)const{ 返回std::forward(t)+std::forw
CallFuncs(1,2, Add, Mul);
或显式类型规范:
CallFuncs(1., 2., Add{}, Mul{});
如果T
是void
(例如,在std::plus{}
)中,plus::operator()
推断参数和返回类型。典型的情况如下(稍作简化):
template struct plus{
模板
constexpr自动运算符()(Tp&t,Up&u)const{
返回std::forward(t)+std::forward(u);
}
};
如果可以将模板函数转换为函子类,则可以执行以下操作:
template<> struct plus<void> {
template<typename Tp, typename Up>
constexpr auto operator()(Tp&& t, Up&& u) const {
return std::forward<Tp>(t) + std::forward<Up>(u);
}
};
或者使用更相似的语法:
void FunctionInvokeTest() { CallFuncs(1, 2, Add{}, Mul{}); }
如果无法更改函数,则将其包装在lambda中可能会有所帮助:
constexpr Add add{};
constexpr Mul mul{};
void FunctionInvokeTest() { CallFuncs(1, 2, add, mul); }
将函数参数移动到模板中的解决方法
void FunctionInvokeTest() { CallFuncs(1, 2,
[](auto lhs, auto rhs) { Add(lhs, rhs); },
[](auto lhs, auto rhs) { Mul(lhs, rhs); }); }
模板
使用BinaryOp=void(F,F);//功能类型
//fns现在是一组函数对象,而不是类型
模板
void CallFuncs(fa,fb){
(fns(a,b),…);
};
void FunctionInvokeTest(){
//这些函数现在作为模板参数与所需的数值类型一起传递
CallFuncs(1,2);
}
不过请注意,由于整数参数W,这将使用
int
而不是double
。。很酷,谢谢你!我花了5个小时搜索和阅读书籍,尝试不同的编码方式,在10分钟内从你那里得到了答案。@AlanBirtles我认为这很好。当我们调用std::max(…)时,我们仍然需要将数字指定为1.0而不是1。@WL_Law,我在使用此技术的标准库中添加了一个示例。
template<> struct plus<void> {
template<typename Tp, typename Up>
constexpr auto operator()(Tp&& t, Up&& u) const {
return std::forward<Tp>(t) + std::forward<Up>(u);
}
};
struct Add {
template <typename T>
void operator ()(T a, T b) const { Print(a + b); }
};
struct Sub
{
template <typename T> void operator() (T a, T b) const { Print(a - b); }
};
struct Mul
{
template <typename T> void operator() (T a, T b) const { Print(a * b); }
};
void FunctionInvokeTest() { CallFuncs(1, 2, Add{}, Mul{}); }
constexpr Add add{};
constexpr Mul mul{};
void FunctionInvokeTest() { CallFuncs(1, 2, add, mul); }
void FunctionInvokeTest() { CallFuncs(1, 2,
[](auto lhs, auto rhs) { Add(lhs, rhs); },
[](auto lhs, auto rhs) { Mul(lhs, rhs); }); }
template <typename F>
using BinaryOp = void(F, F); // function type
// fns is now a pack of function objects instead of types
template <typename F, BinaryOp<F>... fns>
void CallFuncs(F a, F b) {
(fns(a, b), ...);
};
void FunctionInvokeTest() {
// the functions are now passed as template arguments alongside the desired numeric type
CallFuncs<float, Add, Mul>(1, 2);
}