Не получается корректно вставить строки в таблицу с использованием шаблонов, пробую так:
template<typename ...Types>
void bind(sqlite3_stmt *stmt, Types ...arg)
{
std::string arr[] = { arg... };
size_t i = 1;
for (auto &e: arr) {
sqlite3_bind_text(stmt, i, e.c_str(), -1, 0 );
i++;
}
}
template<typename ...Types>
void exec(std::string sqlCmd, Types ...arg)
{
sqlite3 *handle;
sqlite3_stmt *stmt;
sqlite3_open("test.db", &handle);
sqlite3_prepare_v2(handle, sqlCmd.c_str(), -1, &stmt, 0);
bind(stmt, arg...);
sqlite3_step(stmt);
}
int main()
{
exec("CREATE TABLE test_table (first_col TEXT, second_col TEXT, third_col TEXT);");
exec("INSERT INTO test_table (first_col, second_col, third_col) VALUES ( ? , ? , ? )",
"val_1",
"val_2",
"val_3");
}
После выполнения в базу строки добавляются в таком виде(какой-то мусор):
first_col second_col third_col
---------- ---------- ----------
�� val_3
�z�x� val_3
����� val_3
Если не выносить код в отдельную функцию bind, все работает нормально. Почему? Я не правильно передаю шаблон переменной длины?
Также если внутри bind объявить const char* arr[]
вместо std::string arr[]
, то все работает нормально.
У вас локальная переменная в функции bind
уничтожается после выхода из функции:
std::string arr[] = { arg... };
Могу посоветовать переписать так:
void bind(sqlite3_stmt *stmt, std::vector<std::string>& arr) // НЕ-const, чтобы временный объект не передать случайно
{
size_t i = 1;
for (auto &e: arr) {
sqlite3_bind_text(stmt, i, e.c_str(), -1, 0 );
i++;
}
}
template<typename ...Types>
void exec(std::string sqlCmd, Types ...arg)
{
sqlite3 *handle;
sqlite3_stmt *stmt;
sqlite3_open("test.db", &handle);
sqlite3_prepare_v2(handle, sqlCmd.c_str(), -1, &stmt, 0);
std::vector<std::string> arr{ arg... };
bind(stmt, arr);
sqlite3_step(stmt);
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Каким образом можно отобразить OpenStreetMap карту средствами C++/Qt (БЕЗ QML)?