如何让接收可调用对象的C++函数模板匹配对应类型,解决编译报错
错误原因
你写的模板中作为SFINAE约束的第四模板参数没有指定默认值,即便你显式指定了前三个模板参数,编译器也无法自动填充该参数,因此抛出参数推导失败的错误。
修复方法
最小改动方案
直接给SFINAE约束的模板参数添加默认指针值即可:
// 把原模板定义行修改为如下,新增末尾的* = nullptr template<typename Function, typename FirstIn , typename SecondIn, typename std::enable_if<std::is_invocable<Function, FirstIn, SecondIn>::value>::type* = nullptr>
修改后你的原有代码即可正常编译通过。
更简洁的C++17优化方案
利用C++17的auto返回值推导能力,你可以省去手动指定参数类型的步骤,调用时无需显式传入模板参数,写法更简洁:
#include <type_traits> #include <functional> #include <string> template<typename Function> auto swapInput(Function f) { return [=]<typename T1, typename T2>(T2 b, T1 a) { static_assert(std::is_invocable_v<Function, T1, T2>, "传入的函数不支持接收对应顺序的两个参数"); return std::invoke(f, a, b); }; } int main() { std::function<bool(std::string, int)> isLength = [](std::string s, int len) {return (s.size() == len); }; // 无需显式指定模板参数,自动推导 std::function<bool(int, std::string)> lengthIs = swapInput(isLength); // 测试调用正常 lengthIs(3, "abc"); // 返回true }
这个方案完全去掉了冗余的模板参数声明,静态断言也保留了原有的参数合法性校验能力。
内容的提问来源于stack exchange,提问作者MatthewJohnHeath
相关产品推荐
相关产品推荐

