Skip to content

return_value_policy::reference fails if operator new is not public #70

Description

@AndrewWalker

In cases where operator new for a class is inaccessible, bound functions that return that type with the return_value_policy::reference will not compile

#include <memory>
#include <iostream>
#include <pybind11/pybind11.h>
using namespace pybind11;

class Foo {
    void *operator new(size_t bytes) throw();
};

Foo gFoo;
Foo& getstmt() {
    return gFoo;
}

PYBIND11_PLUGIN(example) {
    module m("example");
    class_<Foo>(m, "Foo");
    m.def("getstmt", getstmt, return_value_policy::reference);
    return m.ptr();
}

generating errors in type_caster_generic::cast

/usr/local/include/pybind11/cast.h:214:16: error: 'operator new' is a private member of 'Foo'
        return new type(*((const type *) arg));
               ^~~
/usr/local/include/pybind11/cast.h:202:80: note: in instantiation of function template specialization
      'pybind11::detail::type_caster<Foo, void>::copy_constructor<Foo, 0>' requested here
        return type_caster_generic::cast(&src, policy, parent, &typeid(type), &copy_constructor);
                                                                               ^
/usr/local/include/pybind11/pybind11.h:66:39: note: in instantiation of member function
      'pybind11::detail::type_caster<Foo, void>::cast' requested here
            handle result = cast_out::cast(
                                      ^
/usr/local/include/pybind11/pybind11.h:469:22: note: in instantiation of function template
      specialization 'pybind11::cpp_function::cpp_function<Foo &, pybind11::name, pybind11::sibling,
      pybind11::return_value_policy>' requested here
        cpp_function func(std::forward<Func>(f), name(name_),
                     ^
main.cpp:21:7: note: in instantiation of function template specialization 'pybind11::module::def<Foo
      &(&)(), pybind11::return_value_policy>' requested here
    m.def("getstmt", getstmt, return_value_policy::reference);
      ^
main.cpp:8:11: note: implicitly declared private here
    void *operator new(size_t bytes) throw();

The equivalent boost::python example does compile.

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

using namespace boost;
using namespace boost::python;

class Foo {
    void *operator new(size_t bytes) throw();
};

Foo gFoo;
Foo& getstmt() {
    return gFoo;
}

BOOST_PYTHON_MODULE(example)
{
    class_<Foo>("Foo");
    def("getstmt", getstmt, return_value_policy<reference_existing_object>());
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions