0

According to documentation, the assignment here should work, but it doesn't:

#include <boost/python.hpp>
#include <iostream>

int main(int, char **) {
    using namespace boost::python;
    Py_Initialize();

    object test = object(2.05); //this works fine
    test = 3.05;                //compiler error

    std::cout << extract<double>(test) << std::endl;

    Py_Finalize();
    return 0;
}

Here's the compiler output:

g++ -std=c++1y -I/usr/local/Cellar/python3/3.5.0/Frameworks/Python.framework/Versions/3.5/include/python3.5m -I/usr/local/Cellar/boost/1.59.0/include -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"Test.d" -MT"Test.d" -o "Test.o" "../Test.cpp"
../Test.cpp:9:10: error: no viable overloaded '='
    test = 3.05;
    ~~~~ ^ ~~~~
/usr/local/Cellar/boost/1.59.0/include/boost/python/object_core.hpp:241:9: note: candidate function (the implicit move assignment operator) not viable: no known conversion from 'double' to 'boost::python::api::object' for 1st argument
  class object : public object_base
        ^
/usr/local/Cellar/boost/1.59.0/include/boost/python/object_core.hpp:241:9: note: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'double' to 'const boost::python::api::object' for 1st argument
  class object : public object_base
        ^
1 error generated.
make: *** [Test.o] Error 1

The documentation states that:

object msg = "%s is bigger than %s" % make_tuple(NAME,name);

Demonstrates that you can write the C++ equivalent of "format" % x,y,z in Python, which is useful since there's no easy way to do that in std C++.

However, I can't get this to work. Why isn't my boost::python able to auto convert the double? Actually, not just doubles, but any type.

Here's my environment info:

  • OSX Yosemite
  • LLVM 6.1.0
  • Python 3.5.0
  • Boost 1.59.0
  • Eclipse IDE

Edit: this works

int main(int, char **) {
    Py_Initialize();

    //object test = object(2.05); //this works fine
    //test = 3.05;                //compiler error

    str name = "test";
    str NAME = name.upper();
    object msg = "%s is bigger than %s" % make_tuple(NAME,name);

    std::cout<<std::string(extract<const char*>(msg))<<std::endl;

    Py_Finalize();
    return 0;
}

So it's looking like you cannot assign C++ types without first creating a boost::python object as ForEveR is suggesting.

uclatommy
  • 305
  • 4
  • 11

1 Answers1

0

Because object constructor is explicit

  template <class T>
  explicit object(T const& x);

It's forbidden to use implicit conversion like object = T();. You can use following thing:

object test = object(2.05);
Community
  • 1
  • 1
ForEveR
  • 55,233
  • 2
  • 119
  • 133
  • According to the [documentation](http://www.boost.org/doc/libs/1_60_0/libs/python/doc/html/tutorial/tutorial/object.html), implicit conversion should work. Here's the line from the doc that demonstrates: `object msg = "%s is bigger than %s" % make_tuple(NAME,name);` I've updated the question to remove the constructor issue. – uclatommy Jan 16 '16 at 16:13
  • @uclatommy your new example doesn't removed constructor issue, since in `test = 3.05;` temporary object should be constructed from double, that this object should be assigned to test. – ForEveR Jan 16 '16 at 19:49
  • ok, but what you're saying is contrary to what the documentation says. I'll update the example to use the exact code from documentation. – uclatommy Jan 16 '16 at 20:48
  • So looks like the doc isn't actually assigning native c++ types, they are already constructed objects. I've updated the question for the example that works. However, from what I've read, boost::python provides implicit conversion and it should just work. The [FAQ](http://www.boost.org/doc/libs/1_55_0/libs/python/doc/v2/faq.html#topythonconversionfailed) suggested as much. I'll leave this question open a little longer to see if anyone else can provide more info. Thanks for your help. – uclatommy Jan 16 '16 at 21:05