c++ - 如何使用可变参数模板编写通用函数包装器
问题描述
我刚刚开始沉迷于模板的高级使用。我正在尝试为函数编写一个通用包装器,以包装可能导致异常的函数。如果没有发生异常,包装函数应该将实际返回值写入某个引用,然后返回true
。如果发生异常,它只返回false
。
代码
#include <string>
#include <iostream>
#include <functional>
#include <exception>
#include <iomanip>
template<typename TReturn, typename ... TArgs>
bool Try(std::function<TReturn(TArgs...)> &function, typename std::function<TReturn(TArgs...)>::result_type& res, TArgs&...args) {
try {
res = function(std::forward<TArgs>(args)...);
return true;
}
catch (...) {
return false;
}
}
std::string foo(int val) {
if (val == 0) {
throw std::exception();
}
return "result";
}
int main() {
std::string res = "noResult";
//Should be "false=>noResult"
std::cout << std::boolalpha << Try(foo, res, 0) << "=>" << res;
//Should be "true=>result"
std::cout << std::boolalpha << Try(foo, res, 1) << "=>" << res;
}
期望
我期望像这样的模板实例化bool Try(std::function<std::string(int)>& function, std::string& res, int&arg);
相反,它甚至没有编译:
错误:
没有函数模板“Try”的实例与参数列表匹配
和
'bool Try(std::function<_Ret(_Types...)>,std::function<_Ret(_Types...)>::result_type &,TArgs &...)': 无法推导出模板参数'std::function<_Ret(_Types...)>' 来自'std::string (int)'
我想我打电话的方式Try
也可能有缺陷。
我发现了这个类似的问题,但我无法让它与返回类型一起使用。
是的,对于返回的函数,需要有一个特殊的重载void
。
我错过了什么,怎么能做到这一点?提前致谢!
解决方案
为什么这么多std::function
?
template<typename TReturn, typename ... TArgs>
bool Try(TReturn (&function)(TArgs...), TReturn& res, TArgs...args) {
try {
res = function(std::forward<TArgs>(args)...);
return true;
}
catch (...) {
return false;
}
}
您也不能像0
作为参考一样传递参数TArgs&...
。照原样通过它们。
推荐阅读
- ios - 如何在 Azure Pipelines 中使用 Xcode 任务?
- jquery - jQuery - 如何在滚动时淡出粘性按钮
- firebase-authentication - Firebase 身份验证电子邮件已在使用中错误?
- gem5 - gem5中的乘以循环变量
- javascript - 并行使用 async / await 并在结果到达时获得结果?
- asp.net-core - 通过 Visual Studio 2019 运行 ASP.NET Core 应用程序
- javascript - 尽管模仿了一个工作组件,但 VueJS 给了我一个“未知的自定义元素”错误
- php - 是否可以将枢轴上的表格与雄辩的 ORM 相关联?
- html - wget 命令下载网页并重命名带有 html 标题的文件?
- php - 侧边栏出现在自定义帖子页面上而不被调用