Python 如何将float传递给需要int的pybind11函数

Python 如何将float传递给需要int的pybind11函数,python,c++,python-3.x,pybind11,Python,C++,Python 3.x,Pybind11,我复制了pybind11文档中的示例: #include <pybind11/pybind11.h> namespace py = pybind11; int add(int i, int j) { return i + j; } PYBIND11_MODULE(example, m) { m.def("add", &add, "A function which adds two numbers"); } 然后: $p

我复制了pybind11文档中的示例:

#include <pybind11/pybind11.h>
namespace py = pybind11;
int add(int i, int j) {
    return i + j;
}
PYBIND11_MODULE(example, m) {
    m.def("add", &add, "A function which adds two numbers");
}
然后:

$python3
Python 3.7.3(默认值,2020年7月25日,13:03:44)
linux上的[GCC 8.3.0]
有关详细信息,请键入“帮助”、“版权”、“信用证”或“许可证”。
>>>从示例导入*
>>>加(1、2)
3.
>>>添加(1.0、2.0)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:add():函数参数不兼容。支持以下参数类型:
1.(arg0:int,arg1:int)->int
调用时使用:1.0、2.0
>>>
我意识到我可以重写
add
以获取
两个
参数,然后在
add
的主体中截断它们。但是有没有一种方法可以告诉pybind11将浮点值传递给函数(即使它接受
int
参数)并让它自动执行转换


根据文档,相反的操作(从整数类型转换为
double
)是隐式自动完成的。

C++是强类型的。只有在安全的情况下,它才会对基本类型进行自动类型转换。因为一个整数不能表示一个双C++可以自动执行转换的值。因此,您需要自己显式地进行转换。我不确定这在python中是如何实现的。在C++中,最好用:

#include \<cmath\>

double dbl = 3.5;

int newval = std::round(dbl);
#包括\
双dbl=3.5;
int newval=std::round(dbl);

默示且隐式地截断到
int
是一件可怕的事情,而
pybind11
不会为您这样做。如果必须允许,可以为每种参数类型创建一个重载函数,并让
double
变量代表您进行截断(请记住,这可能不仅仅是在小数点后失去精度;
double
可以表示比任何整数类型大得多的数字,因此这类数字会发生糟糕的事情)

这样做的一个粗略示例是:

#include <pybind11/pybind11.h>
namespace py = pybind11;
int add_int(int i, int j) {
    return i + j;
}
int add_double_as_int(double i, double j) {
    return add_int((int)i, (int)j);
}

PYBIND11_MODULE(example, m) {
    m.def("add", &add_int, "A function which adds two integers");
    m.def("add", &add_double_as_int, "A function which adds two floats after truncating to int");
}
#包括
名称空间py=pybind11;
整数加整数(整数i,整数j){
返回i+j;
}
int加上double作为int(double i,double j){
返回add_int((int)i,(int)j);
}
PYBIND11_模块(示例,m){
m、 def(“add”和add_int,“一个添加两个整数的函数”);
m、 def(“add”、&add_double_as_int”,一个在截断为int后添加两个浮点的函数);
}

在C++级别,函数有不同的名称(可能会用创造性的方法避免这种情况,但这不值得麻烦),但是在Python级别,它们将作为一个单一的API出现在文档中描述的多个原型。

#include \<cmath\>

double dbl = 3.5;

int newval = std::round(dbl);
#include <pybind11/pybind11.h>
namespace py = pybind11;
int add_int(int i, int j) {
    return i + j;
}
int add_double_as_int(double i, double j) {
    return add_int((int)i, (int)j);
}

PYBIND11_MODULE(example, m) {
    m.def("add", &add_int, "A function which adds two integers");
    m.def("add", &add_double_as_int, "A function which adds two floats after truncating to int");
}