我正在尝试扩展std::packaged_task
来处理SEH异常,但无法对其进行编译。
以下内容无法编译:
#include <stdio.h>
#include <functional>
#include <future>
#include <windows.h>
template<class RET, class... ARGS>
class SafePackagedTask : public std::packaged_task<RET(ARGS...)>
{
public:
template<class F>
explicit SafePackagedTask(F && f)
: std::packaged_task*(std::forward<F>(f))
{
}
void operator()(ARGS... args)
{
__try
{
std::packaged_task*(std::forward<ARGS>(args));
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
printf("SEH Exception 0x%08lX in SafePackagedTask!\n", GetExceptionCode());
}
}
};
int main()
{
SafePackagedTask<int()> task([] {
//int *a = nullptr; *a = 1; // generate SEH
return 1;
});
std::future<int> fut = task.get_future();
task();
int rc = fut.get();
printf("result: %d\n", rc);
}
错误是:
source_file.cpp(9): error C2091: function returns function
source_file.cpp(37): note: see reference to class template instantiation 'SafePackagedTask<int (void)>' being compiled
source_file.cpp(38): error C2440: 'initializing': cannot convert from 'std::future<_Ret>' to 'std::future<int>'
with
[
_Ret=int (__cdecl *)(void)
]
source_file.cpp(38): note: No constructor could take the source type, or constructor overload resolution was ambiguous
在rextester.com上查看。
最佳答案
您正在尝试解决已经解决的问题。
通过在VC ++上设置特定标志(您显然正在使用),可以像常规C ++标准异常一样处理SEH异常*
转到项目-> C / C ++->代码生成->在“是,有SEH例外”上设置“启用C ++例外”。
现在您可以使用catch(...)
子句捕获SEH异常:
try{
}catch(std::exception& e){}
catch(...) {/*your code here*}
除此之外,处理SEH异常的最佳方法不是一开始就创建它们。如果您不尝试超出数组边界的范围,不检查空指针,在需要时使用智能指针并仔细编写类以使用RAII,则可能会消除代码中95%的异常。
*基本上,在Windows上,所有C ++异常都是Windows SEH的子集,并因此实现。