You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

pybind11模板函数myadd无法导入,基础函数add可用问题求助

问题:pybind11模板函数无法导入的原因与解决办法

我基于pybind11的demo尝试使用模板函数,基础函数add能正常导入使用,但模板实例化的myadd无法导入,报错如下:

>>> from example import add
>>> add(2,3)
5L
>>> from example import myadd
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: cannot import name myadd

即使复制文档示例代码,只要涉及模板、shared_ptr等复杂结构都会出现该问题,我的源代码如下:

#include <pybind11/pybind11.h>
#include <iostream>
#include <string>
int add(int i, int j) {
    return i + j;
}

template <class T> //template <typename T> doesn't work as well
T myadd(T a, T b) {
    return a+b;
}
namespace py = pybind11;

PYBIND11_MODULE(example, m) {
    // optional module docstring
    m.doc() = "pybind11 example plugin";

    // define add function
    m.def("add", &add, "A function which adds two numbers");
    m.def("myadd", &myadd<int>);
    m.def("myadd", &myadd<float>);
}

原因与解决办法

  • 当前写法多次调用m.def("myadd", ...),会导致后注册的函数覆盖前一个,最终只有最后一个实例(myadd<float>)被绑定,但pybind11无法自动让Python识别这种重载,所以导入时找不到函数名。

  • 正确做法是用pybind11的重载机制,两种实现方式:

    1. 使用py::overload_cast明确参数类型,帮助Python识别重载:
      m.def("myadd", py::overload_cast<int, int>(&myadd<int>), "Add two integers");
      m.def("myadd", py::overload_cast<float, float>(&myadd<float>), "Add two floats");
      
    2. 强制转换函数指针类型,明确签名:
      m.def("myadd", (int(*)(int, int))&myadd<int>, "Add two integers");
      m.def("myadd", (float(*)(float, float))&myadd<float>, "Add two floats");
      
  • 另外检查编译过程:确保模板实例化没有被编译器优化掉(你已经显式取了函数指针,一般不会有这个问题,但如果编译时有警告需要留意)。

修改后Python端就能正常导入myadd,并根据参数类型自动调用对应版本:

>>> from example import myadd
>>> myadd(2, 3)
5
>>> myadd(2.5, 3.5)
6.0

内容的提问来源于stack exchange,提问作者Vladislav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 15:19:31