我正在使用 SQLite3 后端在 C++ SOCI 库中尝试对象关系映射。但是,当我尝试从数据库REAL
值加载为 C++ 的 double 时,std::bad_cast
就会抛出异常。
完整代码:
#include <iostream>
#include <string>
#include <exception>
#include <soci/soci.h>
#include <soci/sqlite3/soci-sqlite3.h>
using namespace std;
using namespace soci;
struct Employee
{
int id;
std::string name;
double salary;
};
ostream& operator<<(ostream& o, const Employee& employee)
{
return o << "Employee(" << employee.id << "):" << employee.name << ", earns: " << employee.salary;
}
namespace soci
{
template<>
struct type_conversion<Employee>
{
typedef values base_type;
static void from_base(const values & v, indicator /* ind */, Employee & employee)
{
employee.id = v.get<int>("ID");
employee.name = v.get<std::string>("Name");
cout << "Type: " << v.get_properties("Salary").get_data_type() << endl; // the output is 0, so the type is soci::dt_string but not soci::dt_double
if (v.get_indicator("Salary") == i_ok)
employee.salary = v.get<double>("Salary");
}
static void to_base(const Employee& employee, values& v, indicator& ind)
{
v.set("ID", employee.id);
v.set("Name", employee.name);
v.set("Salary", employee.salary, employee.salary == 0. ? i_null : i_ok);
ind = i_ok;
}
};
}
int main()
{
try
{
soci::session sql(sqlite3, "employees.db");
sql << "CREATE TABLE IF NOT EXISTS Employees(" \
"ID INT PRIMARY KEY NOT NULL," \
"Name TEXT NOT NULL," \
"Salary REAL);";
sql << "INSERT INTO Employees (ID, Name, Salary) " \
"VALUES (1, 'Janusz Korwin-Mikke', 12000.01 ); ";
Employee employee = {};
sql << "SELECT * FROM Employees WHERE ID = 1;", into(employee);
cout << employee << endl;
}
catch (const exception &e)
{
cerr << "Error: " << e.what() << endl;
}
}
当我运行代码时,我看到std::bad_cast
行中抛出的异常:
employee.salary = v.get<double>("Salary");
尽管在数据库中它是REAL
类型。当我将行更改为:
employee.salary = atof(v.get<std::string>("Salary").c_str());
我正在使用 SOCI-4.0.0,但以前的版本 3.2.3 也有同样的问题,我在 Windows 7 和 MinGW 编译器 7.3.0 上使用 SQLite3