C++17 Qt 使用标准库绑定可变参数包的sql query语句

主要思路是使用std::forward_as_tuple将参数包保存到元组中,然后利用std::apply遍历元组中的数据
这里需要用到auto类型推断,如果参数中有自定义类型还需要注册元对象系统
最后在apply中使用折叠表达式展开参数包(xxxx(args), …)并逐一处理

// consider to use exception?
    template<typename... Args>
    void transaction(
        const QString& queryStat,
        std::function<void(QSqlQuery&)> process = std::function<void(QSqlQuery&)>(),
        Args&&... args
    ) const {
        QSqlQuery query(m_db);
        query.prepare(queryStat);
        
        auto argTuple = std::forward_as_tuple(args...);
        std::apply([&query, this](auto&&... args) {
            ((query.addBindValue(QVariant::fromValue(args)), std::cout << args), ...);
        }, argTuple);
        
        query.exec();
//        qDebug() << (
//            query.lastError().text().isEmpty()?
//            _query + "succeed":
//            query.lastError().text()
//        );
        if(query.lastError().text().isEmpty()) {
            qDebug() << "[SQL TRANSACTION] " + queryStat + " succeed";
            while(query.next()) {
                process(query); // query.value(index).toAnyDataFormat
            }
            return;
        } else {
            qDebug() << query.lastError().text();
            return;
        }
    }

以 下 部 分 无 效 , 仅 供 参 考 \color{red}{以下部分无效,仅供参考}

单元测试


class Test {
public:
    Test() = default;
    explicit Test(int a):m_a(a) {}
    
    friend const std::ostream& operator<< (
        std::ostream &os,
        const Test &t
    ) {
        (void)t.m_a;
        return os << "test";
    }
    
private:
    int m_a = 0;
};

Q_DECLARE_METATYPE(Test)

void TestCompileArglistQuery() {
    auto  f =3;
    QVariant d;
    qDebug() << d.fromValue(f);
    qDebug() << d;
    
    ORMHelper().prepare("UPDATE USER", 0, 2, Test(0), 4, 5);
}

执行结果

QVariant(int, 3)
QVariant(Invalid)
02test45
failed
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++17中引入了新的语法`constexpr if`和折叠表达式,可以更方便地实现可变参数函数调用。 具体实现方式如下: 1. 定义一个模板函数,函数模板参数含一个参数。 2. 在函数体中使用`constexpr if`和折叠表达式来展开参数,以实现对可变参数的遍历操作。 下面是一个简单的例子,实现可变参数函数的调用: ```c++ #include <iostream> #include <cstdio> using namespace std; template<typename... Args> void my_printf(const char* fmt, Args... args) { while (*fmt) { if (*fmt == '%' && *(fmt + 1) != '%') { if constexpr (std::is_same_v<int, std::decay_t<decltype(args)>>) { cout << va_arg(args, int) << endl; } else if constexpr (std::is_same_v<const char*, std::decay_t<decltype(args)>>) { cout << va_arg(args, const char*) << endl; } else { // Other types } fmt += 2; } else { cout << *fmt << endl; fmt++; } } } int main() { my_printf("Hello %s!\n", "world"); my_printf("The value of pi is %d.\n", 3); return 0; } ``` 在上面的例子中,我们定义了一个`my_printf`函数,该函数的第一个参数是一个`const char*`类型的字符串,用于格式化输出,后面的参数是一个可变参数列表,可以是任意类型的值。在函数体中,我们使用了`constexpr if`和折叠表达式来根据参数类型来输出不同的结果。 需要注意的是,在使用可变参数的时候,应该尽量避免类型转换和参数类型不一致的问题,以保证程序的正确性和可读性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值