1

I am working on a pybind11 wrapper for libnest2d. Unfortuately I am not well versed in modern C++ templating and got stuck with this overload problem. I tried to resolve it using the py::overload_cast (see src/main.cpp at the bottom) but the problem still remains. Any hints on how to analyse/solve this would be more than welcome.

what the compiler has to say:

    /usr/bin/c++  -DBOOST_ALL_NO_LIB -DLIBNEST2D_GEOMETRIES_clipper -DLIBNEST2D_OPTIMIZER_nlopt -DLIBNEST2D_THREADING_std -Dnest2d_EXPORTS -I/home/mark/devel/14_2D_3D/nest2d/lib/pybind11/include -I/usr/include/python3.8 -I/home/mark/devel/14_2D_3D/nest2d/lib/libnest2d/include -isystem /usr/include/polyclipping  -DVERSION_INFO=\"0.1.0\" -O3 -DNDEBUG -fPIC -fvisibility=hidden   -std=c++14 -flto -fno-fat-lto-objects -o CMakeFiles/nest2d.dir/src/main.cpp.o -c /home/mark/devel/14_2D_3D/nest2d/src/main.cpp
    /home/mark/devel/14_2D_3D/nest2d/src/main.cpp: In function ‘void pybind11_init_nest2d(pybind11::module&)’:
    /home/mark/devel/14_2D_3D/nest2d/src/main.cpp:62:85: error: no match for call to ‘(const pybind11::detail::overload_cast_impl<std::vector<libnest2d::_Item<ClipperLib::Polygon>, std::allocator<libnest2d::_Item<ClipperLib::Polygon> > >&, const libnest2d::_Box<ClipperLib::IntPoint>&>) (<unresolved overloaded function type>)’
       62 |     m.def("nest", py::overload_cast<std::vector<Item>&, const Box&>(&libnest2d::nest)
          |                                                                                     ^
    In file included from /home/mark/devel/14_2D_3D/nest2d/lib/pybind11/include/pybind11/pytypes.h:12,
                     from /home/mark/devel/14_2D_3D/nest2d/lib/pybind11/include/pybind11/cast.h:13,
                     from /home/mark/devel/14_2D_3D/nest2d/lib/pybind11/include/pybind11/attr.h:13,
                     from /home/mark/devel/14_2D_3D/nest2d/lib/pybind11/include/pybind11/pybind11.h:44,
                     from /home/mark/devel/14_2D_3D/nest2d/src/main.cpp:1:
    /home/mark/devel/14_2D_3D/nest2d/lib/pybind11/include/pybind11/detail/common.h:736:20: note: candidate: ‘template<class Return> constexpr decltype (pf) pybind11::detail::overload_cast_impl<Args>::operator()(Return (*)(Args ...)) const [with Return = Return; Args = {std::vector<libnest2d::_Item<ClipperLib::Polygon>, std::allocator<libnest2d::_Item<ClipperLib::Polygon> > >&, const libnest2d::_Box<ClipperLib::IntPoint>&}]’
      736 |     constexpr auto operator()(Return (*pf)(Args...)) const noexcept
          |                    ^~~~~~~~
    /home/mark/devel/14_2D_3D/nest2d/lib/pybind11/include/pybind11/detail/common.h:736:20: note:   template argument deduction/substitution failed:
    /home/mark/devel/14_2D_3D/nest2d/src/main.cpp:62:85: note:   couldn’t deduce template parameter ‘Return’
       62 |     m.def("nest", py::overload_cast<std::vector<Item>&, const Box&>(&libnest2d::nest)
          |                                                                                     ^
    In file included from /home/mark/devel/14_2D_3D/nest2d/lib/pybind11/include/pybind11/pytypes.h:12,
                     from /home/mark/devel/14_2D_3D/nest2d/lib/pybind11/include/pybind11/cast.h:13,
                     from /home/mark/devel/14_2D_3D/nest2d/lib/pybind11/include/pybind11/attr.h:13,
                     from /home/mark/devel/14_2D_3D/nest2d/lib/pybind11/include/pybind11/pybind11.h:44,
                     from /home/mark/devel/14_2D_3D/nest2d/src/main.cpp:1:
    /home/mark/devel/14_2D_3D/nest2d/lib/pybind11/include/pybind11/detail/common.h:740:20: note: candidate: ‘template<class Return, class Class> constexpr decltype (pmf) pybind11::detail::overload_cast_impl<Args>::operator()(Return (Class::*)(Args ...), std::false_type) const [with Re

src/main.cpp:

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

#include <libnest2d/libnest2d.hpp>

namespace py = pybind11;

using Point = libnest2d::Point;
using Box = libnest2d::Box;
using Item = libnest2d::Item;

PYBIND11_MODULE(nest2d, m)
{
    m.doc() = "2D irregular bin packaging and nesting for python";

    py::class_<Point>(m, "Point", "2D Point")
        .def(py::init<int, int>(),  py::arg("x"), py::arg("y"))
        //.def_property_readonly("x", &Point::X) // TODO
        //.def_property_readonly("y", &Point::Y)
        .def("__repr__",
             [](const Point &p) {
                 std::string r("Point(");
                 r += boost::lexical_cast<std::string>(p.X);
                 r += ", ";
                 r += boost::lexical_cast<std::string>(p.Y);
                 r += ")";
                 return r;
             }
        )
        .def("__eq__",
            [](const Point &p, const Point & q) {
                return p == q;
            }
        );

    // see lib/libnest2d/include/libnest2d/geometry_traits.hpp
    py::class_<Box>(m, "Box", "2D Box point pair")
        .def(py::init<int, int>())
        ;

    // Item is a shape defined by points
    // see lib/libnest2d/include/libnest2d/nester.hpp
    py::class_<Item>(m, "Item", "An item to be placed on a bin.")
        .def(py::init<std::vector<Point>>())
        .def("__repr__",
             [](const Item &i) {
                 std::string r("Item area: ");
                 r += boost::lexical_cast<std::string>(i.area());
                 return r;
             }
        )
        ;

    // The nest function takes two parameters input and box
    // see lib/libnest2d/include/libnest2d/libnest2d.hpp
    m.def("nest", py::overload_cast<std::vector<Item>&, const Box&>(&libnest2d::nest)
        )
        ;

}

to make this a MRE we need the CMakeLists.txt (cmake build) as well:

cmake_minimum_required(VERSION 2.8.12)

set(CMAKE_VERBOSE_MAKEFILE ON)

project(nest2d)

# Boost and its components
find_package( Boost REQUIRED )

if ( NOT Boost_FOUND )

    message(STATUS "This project requires the Boost library, and will not be compiled.")

    return()

endif()

add_subdirectory(lib/pybind11)
add_subdirectory(lib/libnest2d)

pybind11_add_module(nest2d src/main.cpp)
target_link_libraries(nest2d PUBLIC libnest2d)
4
  • Simply means that the overload (i.e. one with parameters std::vector<Item>&, const Box&) can not be matched. If I found the correct header, then it looks like nest requires at least 5 parameters. Commented Dec 26, 2019 at 20:41
  • the "simple" c++ example from the README.md uses only two parameters (this works): size_t bins = nest(input, Box(150000000, 150000000)); so it appears the parameter count is not the problem. Commented Dec 26, 2019 at 22:35
  • 2
    That is very different: when calling a function, defaults are considered and do not need to be provided explicitly. Here, however, is a template resolution to create a cast, not a function call. Commented Dec 26, 2019 at 23:09
  • that is great insight and was instrumental for resolving this issue. Thank you so much! Commented Dec 29, 2019 at 9:09

1 Answer 1

5

The issue was related to the number of parameters used in the cast. I was too focused on the implementation of the simple case to see this at first. Thanks to Wim Lavrijsen for pointing this out (see comments). I found that in this case I don't need the overload_cast at all but can explicitly relay the call.

m.def("nest", [](std::vector<Item> input, const Box& box) {
        return libnest2d::nest(input, box);
    }
    );
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.