QTimer单发,通过lambda捕获异常

QTimer single shot, passing lambda with exception in capture

我正在使用 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):警告 C4702:无法访问的代码。 知道出了什么问题吗? 从捕获中删除 e 并将 lambda 留空可以解决问题,所以看起来它与此相关吗?谢谢

这基本上是噪音,您可以忽略该警告。它来自 Qt 包装函子的方式。代码 around the error location 如下所示:

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 没有 return 值,因此 the overridden operator, does nothing:

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

所以你可以selectively disable that warning for that bit of code only,即:

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); 而不是零计时器,尽管不可否认它更多的是文本,所以我想这取决于个人的喜好,没有明显更好的语法。