【发布时间】:2021-04-05 23:36:17
【问题描述】:
我最近发现了SQLite,它对我来说似乎是一个很棒的嵌入式数据库。我能找到的唯一(也是非常小的)问题是关于它的 C 接口以及它如何迫使您输入大量样板代码,所以我想知道使用可变参数模板和 C++17 折叠功能是否可以改进那一点。
不幸的是,我知道我想要什么,但我无法自己开发它。
解决方案的理想先决条件:
- 基于 C++17 或更低版本(但遗憾的是不是 C++20)的解决方案
- 摆脱辅助模板专门功能应该是一个高加分(也许
if constexpr(type_trait)的巧妙使用?)
这是我当前的代码,以及可变参数模板函数应如何表现的注释示例:
#include <iostream>
#include <tuple>
// Fake mock pretending the interface for SQLite3 (just to avoid have to install, link and include the real project).
// Please, do NOT change anything here.
unsigned char buffer[] = { 't', 'e', 's', 't' };
const int sqlite3_column_int(int iCol) { return 5; }
const unsigned char* sqlite3_column_text(int iCol) { return buffer; }
// End of unmodificable mock.
// Auxiliary functions:
template<typename T>
T sqlite3_column(int col);
template<>
int sqlite3_column<int>(int col) { return sqlite3_column_int(col); }
template<>
std::string sqlite3_column<std::string>(int col) { return reinterpret_cast<const char*>(sqlite3_column_text(col)); }
// What I would like to have available:
template<typename... Args>
auto sqlite3_record() -> std::tuple<Args...>
{
return std::make_tuple((sqlite3_column<Args>(N?),...));
}
//It should behabe as this example:
//std::tuple<int, int, std::string, std::string> sqlite3_record_example()
//{
// return std::make_tuple( sqlite3_column<int>(0), sqlite3_column<int>(1), sqlite3_column<std::string>(2), sqlite3_column<std::string>(3) );
//}
int main()
{
auto [i1, i2, s1, s2] = sqlite3_record<int, int, std::string, std::string>();
std::cout << i1 << " / " << i2 << " / " << s1 << " / " << s2;
//It should return 5 / 5 / test / test
}
这是一个 Coliru 链接:http://coliru.stacked-crooked.com/a/52e5acd9d92a39e8
请原谅可怕的N?模板参数的地方。
【问题讨论】:
标签: c++ c++17 variadic-templates fold