Discussion:
[soci-users] boost::tuple with boost::optional<std::string> throws a bad::cast exception using soci::into
Ricardo Muñoz
2013-04-21 09:38:32 UTC
Permalink
Hi, I've been trying to use boost::tuple with a boost::optional element and
I get a bad::cast exception. Attached to this mail you can find the
complete test case but here is small code snippet:

That works:
row_type get_last_row(soci::session& sql)
{
unsigned int id = 0;
std::string str1;
boost::optional<std::string> str2;

sql << "SELECT id, str1, str2 from example ORDER BY id DESC LIMIT 1",
soci::into(id), soci::into(str1), soci::into(str2);

return row_type(id, str1, str2);
}

That does not:
row_type get_last_row2(soci::session& sql)
{
row_type myrow;

try
{
sql << "SELECT id, str1, str2 from example ORDER BY id DESC LIMIT 1",
soci::into(myrow);
}
catch(const std::exception& e)
{
std::cout << "Exception: " << e.what() << std::endl;
}

return myrow;
}

Probably i'm missing something, but I can't find it.

Thanks in advance.
Mateusz Loskot
2013-04-26 11:15:51 UTC
Permalink
This post might be inappropriate. Click to display it.
Ricardo Muñoz
2013-05-04 06:59:05 UTC
Permalink
Thanks for your explanation!

Regards,
Post by Ricardo Muñoz
Post by Ricardo Muñoz
Hi, I've been trying to use boost::tuple with a boost::optional element
and
Post by Ricardo Muñoz
I get a bad::cast exception. Attached to this mail you can find the
complete
Post by Ricardo Muñoz
row_type get_last_row(soci::session& sql)
{
unsigned int id = 0;
std::string str1;
boost::optional<std::string> str2;
sql << "SELECT id, str1, str2 from example ORDER BY id DESC LIMIT 1",
soci::into(id), soci::into(str1), soci::into(str2);
This is simple conversion that is performed by SQLite 3 backend itself
which translates SQL type to C++ type as implemented in
sqlite3_standard_into_type_backend::post_fetch
Post by Ricardo Muñoz
row_type get_last_row2(soci::session& sql)
{
row_type myrow;
try
{
sql << "SELECT id, str1, str2 from example ORDER BY id DESC LIMIT 1",
soci::into(myrow);
Shortly, this is known issue related to this report
https://github.com/SOCI/soci/issues/90
The row_type is mapped to dynamic-typed objects wrapped with type_holder
This is involves more complex conversion using the common layer
of type_conversion specialisations, and here is the problem.
If you look at type_conversion<unsigned int> in unsigned-types.h, you can see
a little hack for base_type being long long.
Now, at binding, statements creates type_holder<int> according to
bind_into<dt_integer> mapping in statement_impl - there is no
dt_unsigned_integer.
But, the conversion goes through type_holder<long long> which leads to
type_holder<T>* p = dynamic_cast<type_holder<T> *>(this);
as this is type_holder<int> but T is long long, unrelated types.
Long story short, this is all related to lack of complete C++ integer
types support.
Best regards,
--
Mateusz Loskot, http://mateusz.loskot.net
------------------------------------------------------------------------------
Try New Relic Now & We'll Send You this Cool Shirt
New Relic is the only SaaS-based application performance monitoring service
that delivers powerful full stack analytics. Optimize and monitor your
browser, app, & servers with just a few lines of code. Try New Relic
and get this awesome Nerd Life shirt! http://p.sf.net/sfu/newrelic_d2d_apr
_______________________________________________
soci-users mailing list
https://lists.sourceforge.net/lists/listinfo/soci-users
Loading...