std::tr1::shared_ptr and C++ Singletons
Hello, I have 2 problems: 1) class_<Foo, std::tr1::shared_ptr<Foo> > doesn't work=compile errors while boost::shared_ptr does. In the code I am writing bindings for std::tr1::shared_ptr is used. 2) I am not sure how to handle C++ Singletons. I thought that the proper way is to use return_value_policy<reference_existing_object>() for functions returning pointers to them as described in [1], but at the bottom of [2] Dave seems to disagree or I am missing something. Btw. how would you handle the situation when the get_it() is a method of object you want to get? I used: def("get_it", &Foo::get_instance, return_value_policy<reference_existing_object>()); Is it the best solution? [1] - http://www.boost.org/libs/python/doc/v2/reference_existing_object.html [2] - http://mail.python.org/pipermail/c++-sig/2005-January/008481.html -- Best Regards, Piotr Jaroszynski
Hi! I have a base class that serves as implementation detail (not a class to be exposed to Python). That class defines a pair of begin/end member functions to access some iterator (classic). When I want to expose the range either as __iter__ or some property, I get errors like this: Traceback (most recent call last): File "<string>", line 1, in ? Boost.Python.ArgumentError: Python argument types in None.None(TheClass) did not match C++ signature: None(boost::python::back_reference<Base&>) Here is the sample code illustrating the problem: #include <boost/python.hpp> #include <vector> using namespace ::boost::python ; struct Base // meant as implementation detail { private : // private to illustrate that the exact type is not available // outside the class typedef ::std::vector< int > int_seq ; public : typedef int_seq::const_iterator const_iterator ; int_seq seq ; const_iterator begin() const { return seq.begin() ; } const_iterator end() const { return seq.end() ; } } ; struct TheClass : Base { TheClass() { seq.resize( 1 , 1 ) ; // just to put something in for the example } } ; BOOST_PYTHON_MODULE( iter_from_base ) { class_< TheClass >( "TheClass" ) // Both have problems: .def( "__iter__" , range( & TheClass::begin , & TheClass::end ) ) .add_property( "seq" , range( & TheClass::begin , & TheClass::end ) ) ; } The only way I found to work this out is, aside from exposing the base class, to wrap the begin/end functions, e.g.: TheClass::const_iterator wrap_begin( const TheClass& c ) { return c.begin() ; } TheClass::const_iterator wrap_end( const TheClass& c ) { return c.begin() ; } BOOST_PYTHON_MODULE( iter_from_base ) { class_< TheClass >( "TheClass" ) // Both have problems: .def( "__iter__" , range( & wrap_begin , & wrap_end ) ) ; } Which is a little bit inconvenient. Would there be any way to fix this otherwise? -- François Duranleau LIGUM, Université de Montréal
1) class_<Foo, std::tr1::shared_ptr<Foo> > doesn't work=compile errors while boost::shared_ptr does. In the code I am writing bindings for std::tr1::shared_ptr is used. The fix is rather simple, one needs to declare the following get_pointer template before including boost/python.hpp. Maybe it's worth adding to the boost?
namespace boost { template<class T> inline T * get_pointer(std::tr1::shared_ptr<T> const & p){ return p.get(); } } -- Best Regards, Piotr Jaroszynski
Piotr Jaroszynski wrote:
1) class_<Foo, std::tr1::shared_ptr<Foo> > doesn't work=compile errors while boost::shared_ptr does. In the code I am writing bindings for std::tr1::shared_ptr is used. The fix is rather simple, one needs to declare the following get_pointer template before including boost/python.hpp. Maybe it's worth adding to the boost?
namespace boost { template<class T> inline T * get_pointer(std::tr1::shared_ptr<T> const & p){ return p.get(); } }
As I said on IRC: I don't think this is 'correct', as boost and tr1 are two disjunct sets of APIs. I don't know the details of how the converters work, but I'd guess just declaring the above get_pointer() function so it makes its way into the overload set seen when the compiler instantiates the conerter harness should be enough. If it isn't, a (simple, minimal) test case may be a good idea. :-) Regards, Stefan -- ...ich hab' noch einen Koffer in Berlin...
As I said on IRC: I don't think this is 'correct', as boost and tr1 are two disjunct sets of APIs. I don't know the details of how the converters work, but I'd guess just declaring the above get_pointer() function so it makes its way into the overload set seen when the compiler instantiates the conerter harness should be enough. Seems you were at least partially right. I did some addition research and testcases follow.
If it isn't, a (simple, minimal) test case may be a good idea. :-) Here we go: testcase1 - [1] - couldn't be any simpler - compiles just fine testcase2 - [2] - putting foo in the blah namespace breaks - [3] testcase3 - [4] - workaround for testcase2, notice that including the boost/python.hpp before the template definition or not putting the template in the boost namespace breaks it.
[1] - http://dev.gentooexperimental.org/~peper/boost/testcase1.cc [2] - http://dev.gentooexperimental.org/~peper/boost/testcase2.cc [3] - http://dev.gentooexperimental.org/~peper/boost/testcase2_error.txt [4] - http://dev.gentooexperimental.org/~peper/boost/testcase3.cc boost 1.33.1 and gcc 4.1.2. -- Best Regards, Piotr Jaroszynski
participants (3)
-
François Duranleau -
Piotr Jaroszynski -
Stefan Seefeld