如何捕獲拋出的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/)。 –
我實際上不會這樣編碼,我只是想知道它是否可以在理論上工作。我通常儘可能避免在我的真實代碼中出現異常,所以請不要擔心;) –