首页 > 解决方案 > QTimer 单发,在捕获中传递 lambda 异常

问题描述

我正在使用 Qt 5.15.0。我有一个 try-catch 块,如下所示:

try
{
   //some code here
}
catch(std::exception& e)
{
   QTimer::singleShot(0,[e](){ throw e;});
}

我收到一条被视为错误 C4702: QtCore\qobjectdefs_impl.h(146): warning C4702: unreachable code 的警告。知道出了什么问题吗?从捕获中删除 e 并将 lambda 保留为空可以解决问题,所以看起来它与此有关?谢谢

标签: c++qtlambdaqtimer

解决方案


这基本上是噪音,您可以忽略该警告。它来自 Qt 如何包装你的仿函数。错误位置周围的代码如下所示:

template <typename, typename, typename, typename> struct FunctorCall;
template <int... II, typename... SignalArgs, typename R, typename Function>
struct FunctorCall<IndexesList<II...>, List<SignalArgs...>, R, Function> {
    static void call(Function &f, void **arg) {
        f((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[II+1]))...), ApplyReturnValue<R>(arg[0]);
    }
};

编译器抱怨ApplyReturnValue<R>(arg[0])表达式不会被执行。这是一个有效的投诉,但该代码不必运行,所以没有什么可担心的,因为在你的情况下ApplyReturnValue<R>,实际上是ApplyReturnValue<void>因为 lambda 没有返回值,因此重写operator,什么都不做

template<typename T>
    void operator,(T, const ApplyReturnValue<void> &) {}

因此,您可以选择性地仅针对那段代码禁用该警告,即:

try
{
   // some code here
}
catch(std::exception& e)
{
   #pragma warning(push)
   #pragma warning(disable : 4702)
   QTimer::singleShot(0,[e](){ throw e;});
   #pragma warning(pop)
}

而且,如果您知道您正在运行的线程是主线程,则可以使用QMetaObject::invokeMethod(qApp, [e]{ throw e; }, Qt::QueuedConnection);零计时器代替零计时器,尽管不可否认它是更多的文本,所以我想这取决于一个人的偏好,而没有明显更好的语法。


推荐阅读