能否改写testExec函数以支持可变参数,避免使用Lambda?
用C++可变模板参数改造testExec函数,无需Lambda适配
完全可以通过C++11及以上的可变模板参数实现需求,直接接收任意参数数量的目标函数和对应参数列表,不需要额外用Lambda做包装适配。
核心实现思路
让testExec成为模板函数,用typename... Args声明可变参数包,通过完美转发(std::forward)传递参数给目标函数,既保留参数的左值/右值特性,又避免不必要的拷贝开销。结合Qt的交互逻辑,示例代码如下:
#include <functional> #include <QMessageBox> template<typename Func, typename... Args> bool testExec(Func&& func, int maxRetryCount, Args&&... args) { int consecutiveErrors = 0; while (true) { // 调用目标函数,完美转发所有参数 bool success = std::invoke(std::forward<Func>(func), std::forward<Args>(args)...); if (success) { consecutiveErrors = 0; return true; } consecutiveErrors++; if (consecutiveErrors < maxRetryCount) { continue; // 自动重试 } // 达到最大错误次数,询问用户 QMessageBox::StandardButton reply = QMessageBox::question( nullptr, "重试确认", QString("已连续失败%1次,是否继续重试?").arg(maxRetryCount), QMessageBox::Yes | QMessageBox::No ); if (reply == QMessageBox::No) { return false; } consecutiveErrors = 0; // 用户确认继续,重置错误计数 } }
调用示例
- 无参数目标函数:
bool myVoidFunc() { // 示例逻辑:模拟随机失败 return qrand() % 2 == 0; } // 调用:最多重试3次 testExec(myVoidFunc, 3);
- 带参数的目标函数(含Qt类引用参数):
bool writeFile(QFile& file, const QString& content) { if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) return false; QTextStream out(&file); out << content; file.close(); return true; } QFile targetFile("test.txt"); // 注意:左值引用参数需用std::ref包装,避免值传递 testExec(writeFile, 2, std::ref(targetFile), "Hello Qt");
额外说明
std::invoke是C17引入的工具,可统一调用普通函数、成员函数、函数对象等;如果用C11/14,直接替换为func(std::forward<Args>(args)...)即可,但std::invoke对成员函数指针的支持更友好(比如直接传&QFile::open)。- 完美转发确保参数传递的效率,同时兼容各种参数类型(左值、右值、常量引用等)。
内容的提问来源于stack exchange,提问作者Alvein
相关产品推荐
相关产品推荐

