pybind11 icon indicating copy to clipboard operation
pybind11 copied to clipboard

Request for "tagging" arguments with default without needing to duplicate the default values

Open tadeu opened this issue 7 years ago • 1 comments

Could pybind11 support default arguments for constructors without having to repeat the defaults, using something like this:

py::class_<Foo> c(m, "Foo");
c.def(py::init<
    const std::shared_ptr<bar>&,
    const std::array<double, 3>&,
    py::optional<
        const double,
        const double
    >
>());

this would be shortcut for:

py::class_<Foo> c(m, "Foo");

c.def(py::init<
    const std::shared_ptr<bar>&,
    const std::array<double, 3>&,
>());


c.def(py::init<
    const std::shared_ptr<bar>&,
    const std::array<double, 3>&,
    const double
>());

c.def(py::init<
    const std::shared_ptr<bar>&,
    const std::array<double, 3>&,
    const double,
    const double
>());

Note that Boost.Python supports this syntax.

tadeu avatar Sep 12 '18 20:09 tadeu


#include <pybind11/pybind11.h>
#include <pybind11/functional.h>
#include <pybind11/stl.h>
#include <memory>
#include <array>

namespace py = pybind11;

class bar {
public:
    bar() = default;
    void print() const {
        std::cout << "bar print\n";
    }
};

class Foo {
public:
    Foo(const std::shared_ptr<bar>& b,
        const std::array<double, 3>& arr,
        py::optional<double> arg1 = py::none(),
        py::optional<double> arg2 = py::none())
        : b_(b), arr_(arr), arg1_(arg1), arg2_(arg2) {
        // Constructor logic
        if (arg1) {
            std::cout << "arg1: " << *arg1 << "\n";
        }
        if (arg2) {
            std::cout << "arg2: " << *arg2 << "\n";
        }
    }

    void print() const {
        std::cout << "Foo print\n";
    }

private:
    std::shared_ptr<bar> b_;
    std::array<double, 3> arr_;
    py::optional<double> arg1_;
    py::optional<double> arg2_;
};

PYBIND11_MODULE(example, m) {
    py::class_<bar, std::shared_ptr<bar>>(m, "bar")
        .def(py::init<>())
        .def("print", &bar::print);

    py::class_<Foo>(m, "Foo")
        .def(py::init<const std::shared_ptr<bar>&,
                      const std::array<double, 3>&,
                      py::optional<double> = py::none(),
                      py::optional<double> = py::none>())
        .def("print", &Foo::print);
}

ljluestc avatar Nov 23 '24 20:11 ljluestc