I am trying to use boost::any to encapsulate the sqlite return values. I then tried to write a loop to print these.
My first thought was to do something like:
for(boost::any field: row) {
switch(field.type()) {
case typeid(double):
double value = any_cast<double>(field);
...
break;
case typeid(other type):
...
}
}
Now for the experienced programmer it becomes obvious that this can not work since typeid returns an instance rather than a numeric id.
After some research I figured I might try either typeid(...).hash_code()
however this is not sufficiently constexpr
qualified (Beside the danger of hash collision).
if ... else ...
labyrinth to handle objects based on their typeid?hash_code
is not a const_expr
? Is this a result of the separate compilation of object files?std::type_index
? Considering that it only provides some additional operators (<
, <=
, >
, >=
) why was it not possible to integrate its functionality with std::type_info
?I have a feeling you are looking for boost variant and static visitations.
Since variants weren't mentioned, this might be worth posting as an answer. Demonstruction:
#include <sstream>
#include <iostream>
#include <boost/variant.hpp>
using namespace boost;
struct Nil {};
using blob_t = std::vector<uint8_t>;
using field_value_t = boost::variant<Nil, double, char const*, long, blob_t/*, boost::date_time, std::vector<uint8_t>*/>;
struct handler : static_visitor<std::string> {
std::string operator()(double) const { return "double"; }
std::string operator()(char const*) const { return "C string (ew!)"; }
std::string operator()(long) const { return "long"; }
std::string operator()(blob_t) const { return "long"; }
std::string operator()(Nil) const { return "<NIL>"; }
template<typename T>
std::string operator()(T const&) const { throw "Not implemented"; } // TODO proper exception
};
void handle_field(field_value_t const& value) {
std::cout << "It's a " << apply_visitor(handler(), value) << "\n";
}
int main() {
handle_field({});
handle_field(blob_t { 1,2,3 });
handle_field("Hello world");
handle_field(3.14);
}
Prints
It's a <NIL>
It's a long
It's a C string (ew!)
It's a double