使用boost::optional捕获和包装异常
Catching and wrapping exceptions with boost::optional
我想捕获库代码生成的异常,并将它们包装在boost::optional
s(或std::experimental::optional
)中。我的代码可以处理一些琐碎的情况,但是在调用重载函数时很难推断出正确的类型。我将我的测试用例简化为:
// Compile with: clang++ -std=c++14 -stdlib=libc++ -Wall -Wshadow -Wextra -o except_to_optional except_to_optional.cpp
#include <iostream>
#include <boost/optional.hpp>
template<typename Func, typename... Args>
auto try_call(Func f, Args&&... args) noexcept -> boost::optional<std::decay_t<decltype(f(std::forward<Args>(args)...))>>
{
using RT = std::decay_t<decltype(f(std::forward<Args>(args)...))>;
try {
return boost::make_optional<RT>(f(std::forward<Args>(args)...));
} catch(...) {
return boost::none;
}
}
int func1(char * ptr)
{
if (!ptr)
throw 14;
return strlen(ptr);
}
int func1(char * ptr, size_t len)
{
if (!ptr)
throw 14;
const size_t calc_len = strlen(ptr);
return calc_len < len ? calc_len : len;
}
int main(int argc, char **argv)
{
char *omg = "omg";
#if 1
// This is the desired syntax, but it fails
auto val = try_call(func1, omg);
#else
// This works, but its ugly
int (*f)(char *) = func1;
auto val = try_call(f, omg);
#endif
if (val)
std::cout << omg << " has a length of " << *val << "n";
else
std::cout << "Something went wrong...n";
return 0;
}
当尝试编译"broken"示例时,我得到以下输出:
except_to_optional.cpp:50:14: error: no matching function for call to 'try_call'
auto val = try_call(func1, omg);
^~~~~~~~
except_to_optional.cpp:17:6: note: candidate template ignored: couldn't infer template argument 'Func'
auto try_call(Func f, Args&&... args) noexcept -> boost::optional<std::decay_t<decltype(f(std::forward<Args>(args)...))>>
^
我可以通过创建具有正确类型的函数指针来回避这个问题,但这并不理想。是否有一个解决方案,我的问题,或者我坚持与丑陋的函数指针hack?
欢呼,瑞安
在第一种情况下,您可能想要传递两个不同版本的func1
。编译器不知道需要什么类型的func1
来实例化模板,所以它没有"向里面看"模板,看"一个参数"的版本是正确的。
这是编译器错误信息告诉你的。
在第二种情况下,您选择func1
的一个重载并将其传递给try_call
。没有歧义,因此编译器可以找出要应用于模板的签名。
相关文章:
- 处理多个异常集合的C++方法
- 我在c++代码中生成了一个运行时#3异常
- 孤立代码块在结构中引发异常
- 如何在c++17中制作一个模板包装器/装饰器
- C++中的赋值发生,尽管右侧出现异常
- std::vector的包装器,使数组的结构看起来像结构的数组
- 如何在c++迭代器类型中包装std::chrono
- 从构造函数抛出异常时如何克服内存泄漏
- 异常属于C++中的线程还是进程
- 当类定义不可见时捕获异常
- 是否可以用"iostream"包装现有的TCP/OOpenSSL会话
- 抽象包装带有异常的 C 错误处理的最佳方法
- C# 中与 CLI 包装器通信C++未处理的异常
- C++ C# 包装器空异常错误
- 抛出类似可变参数宏包装的函数,替换抛出的异常
- 是否可以在不同的类中编写/包装异常处理组件(try、catch)
- 使用boost::optional捕获和包装异常
- 如何:捕获输入函数异常的可变包装函数
- 你能把一个异常继承层次结构包装到另一个吗?——或者,另一种干净的处理方式
- 在Java应用程序中使用c#包装器和C API时出现异常