In Python itself, you'd write simply float(f)
where f
is a Python Decimal. That yields a double
type (called a float
in Python).
But I need to do this in boost::python
. My code (abridged) is
double toDouble(boost::python::object obj)
{
std::string type = boost::python::extract<std::string>(obj.attr("__class__").attr("__name__"));
std::string module = boost::python::extract<std::string>(obj.attr("__class__").attr("__module__"));
std::string cls = module + "." + type;
if (cls == "decimal.Decimal"){
double f = boost::python::extract<double>(obj);
return f;
}
throw "Oops";
}
But I get an error
No registered converter was able to produce a C++ rvalue of type double from this Python object of type decimal.Decimal
How do I do this? I can't imagine it's complicated. Clearly I'm missing something.
The code you need in the if
block is
static boost::python::object builtins
= boost::python::import("builtins");
static boost::python::object function
= boost::python::extract<boost::python::object>(builtins.attr("float"));
boost::python::object ret = function(obj);
double f = boost::python::extract<double>(ret);
I am indeed essentially using the Python function float(obj)
.
And by the looks of things, you are already familiar with boost::python::extract
.
float
is a built-in python function. See https://docs.python.org/3/library/functions.html. So the first statement is the importing of the module containing the built-in functions. The second statement obtains the float
function.
The third one calls it, on the lines of the Boost documentation "Calling Python Functions And Methods".
You might be able to pull this together to register this extraction, which probably, knowing the beautiful way in which Boost is designed, amounts to little more than specialising a template.