如何捕获作为异常抛出的lambda表达式?我尝试了以下方法:
#include <functional>
int main() {
try {
throw [](){};
} catch (std::function<void()> & fn) {
fn();
}
}
然而输出结果为:
在抛出'main::{lambda()#1}'实例后终止调用
是否可能捕获抛出的lambda异常?
如何捕获作为异常抛出的lambda表达式?我尝试了以下方法:
#include <functional>
int main() {
try {
throw [](){};
} catch (std::function<void()> & fn) {
fn();
}
}
在抛出'main::{lambda()#1}'实例后终止调用
是否可能捕获抛出的lambda异常?
std::function
:int main() {
try {
throw std::function<void()>([](){std::cout << "Hello there!";});
} catch (std::function<void()> & fn) {
fn();
}
}
int main() {
try {
throw [](){};
} catch (std::function<void()> & fn) {
fn();
}
}
以下是导致异常处理程序不会被执行的两个原因:
您通过对 std::function<void()>
对象的 lvalue
引用捕获异常,但抛出的对象既不是该类型,也不是该抛出对象的基类。
即使您将参数更改为值,std::function<void()>
也无法从异常处理中的 lambda 构造。请参见 this。
然而,有方法可以使其“工作”。请参见 SingerOfTheFall和 skypjack的答案。
#include <functional>
#include<utility>
#include<type_traits>
#include<iostream>
struct Base {
virtual void operator()() = 0;
};
template<typename F>
struct Lambda: F, Base {
Lambda(F &&f): F{std::forward<F>(f)} {}
void operator()() override { F::operator()(); }
};
template<typename F>
auto create(F &&f) {
return Lambda<std::decay_t<F>>{std::forward<F>(f)};
}
int main() {
try {
throw create([](){ std::cout << "doh" << std::endl; });
} catch (Base &fn) {
fn();
}
}
std::function
中,这样你就确切地知道你正在捕获什么。
catch(...)
。您甚至可以稍后使用std::exception_ptr
来进行一些技巧操作。 - milleniumbug