2

我知道这里有一个类似的问题:Binding a function with std::initializer_list argument using pybind11但因为我不能评论(没有足够的声誉)我在这里问我的问题:Do the results from the above-linked question also apply to constructors : 即,如果我有一个构造函数,std::initializer_list<T>有没有办法绑定它?

4

1 回答 1

2

至少没有简单的方法可以绑定它。基本上,正如另一篇文章中提到的(以及我在 pybind11 问题跟踪器中的原始回复),我们不能动态构造 a std::initializer_list:它是一个编译时构造。构造函数 vs 方法 vs 函数在这里无关紧要:我们不能将一组动态参数转换为编译时initializer_list构造。

但是让我给你一个方法,如果你真的被需要它的 C++ 设计所困扰,你可以部分地包装它。您首先必须决定要支持多少个论点。例如,假设您要支持在绑定构造函数中通过 a传递的1、2 或 3 个int参数。你可以写:initializer_list<int>MyType

#include <stl.h>

py::class_<MyType>(m, "MyClass")
    .def(py::init([](int a) { return new MyClass({ a }); }))
    .def(py::init([](int a, int b) { return new MyClass({ a, b }); }))
    .def(py::init([](int a, int b, int c) { return new MyClass({ a, b, c }); }))
    .def(py::init([](std::vector<int> v) {
        if (vals.size() == 1) return new MyClass({ v[0] });
        elsif (vals.size() == 2) return new MyClass({ v[0], v[1] });
        elsif (vals.size() == 3) return new MyClass({ v[0], v[1], v[2] });
        else throw std::runtime_error("Wrong number of ints for a MyClass");
    });

其中前三个重载采用整数值作为参数,最后一个采用列表。(没有理由你必须同时使用这两种方法——我只是为了举例)。

这两者都相当粗略,并且不能很好地扩展,但它们展示了一个基本问题:每个大小的 an 都initializer_list需要从不同的 C++ 代码段编译这就是 pybind11 不能支持它的原因:我们必须为每个可能的initializer_list参数长度编译不同版本的转换代码——因此二进制大小可能会因可能使用的任意数量的参数而爆炸,或者存在任意参数大小截止值,超过该值您开始出现致命错误。这些都不是很好的选择。

编辑:至于您关于构造函数的具体问题:这里没有区别。问题是我们无法将参数转换为所需的类型,无论是构造函数、方法还是函数,参数转换都是相同的。

于 2018-03-24T21:53:46.563 回答