如何捕获抛出的lambda作为异常?我试过如下:捕捉lambda异常
#include <functional>
int main() {
try {
throw [](){};
} catch (std::function<void()> & fn) {
fn();
}
}
但是输出
投掷 实例终止后,被称为 '主:: {拉姆达()#1}'
是它可能捕获抛出的lambda异常?
如何捕获抛出的lambda作为异常?我试过如下:捕捉lambda异常
#include <functional>
int main() {
try {
throw [](){};
} catch (std::function<void()> & fn) {
fn();
}
}
但是输出
投掷 实例终止后,被称为 '主:: {拉姆达()#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();
}
}
两个原因是异常处理程序将不会被执行:
您正在追赶你的异常通过lvalue
参考的std::function<void()>
对象,但抛出的对象是该类型的未既不它是抛出对象的基类。
即使您将参数更改为值,std::function<void()>
也不会从异常处理中的lambda构造而成。见this
不过,也有办法让它 “工作”。见答案by SingerOfTheFall和by skypjack
拉姆达有它自己的类型,是不是std::function
。因此,你不捕捉拉姆达,你正在捕捉别的东西,从来没有抛出,可以被分配到std::function
。
要解决这个问题,你可以将lambda直接包装在std::function
或处理程序类中。
作为最小的,工作示例(使用的包装,就是有点滑稽写):
#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();
}
}
时捕获异常是主要的要求对您所捕捉的对象的特定类型。您可以使用Lambda的don't have a specific, clean type。一个干净的方法是用你的Lambda包装std::function
,然后你完全知道你在抓什么。
请记住,每个lambda都是它自己的唯一类型,它没有任何公共基类型。此外,抛出lambda似乎是一个坏主意。 –
此外,抛出一个lambda需要解决的* actual *问题是什么?您向我们展示了一个解决未知问题的通缉解决方案,并请求我们提供该解决方案的帮助,而无需告知我们应该解决什么问题。典型的[XY问题](http://xyproblem.info/)。 –
我实际上不会这样编码,我只是想知道它是否可以在理论上工作。我通常尽可能避免在我的真实代码中出现异常,所以请不要担心;) –