Pybind11中如何访问Python传入的tuple元素?
解决pybind11 tuple访问报错问题
报错翻译
- 使用
get<0>(hw_args_)时的错误:没有匹配的重载函数'get',参数类型为pybind11::tuple - 使用
hw_args_[0]赋值时的错误:不存在从'pybind11::detail::tuple_accessor'到'unsigned int'的合适转换函数
问题原因
pybind11的py::tuple不是C++标准库的std::tuple,没法直接用std::get访问;而py::tuple的operator[]返回的是代理对象tuple_accessor,不能隐式转成unsigned int,必须显式做类型转换。
正确访问方式
有两种实用的解决方法:
方法1:显式转换元素类型
直接对operator[]返回的结果用py::cast转成目标类型:
Buffer::Buffer(int size, py::tuple hw_args_) { // 显式转换tuple元素到unsigned int unsigned int frame_height = py::cast<unsigned int>(hw_args_[0]); unsigned int frame_width = py::cast<unsigned int>(hw_args_[1]); Buffer::time_codes = new int[size]; Buffer::time_stamps = new std::string[size]; // 注意:C++不能直接动态分配三维数组,需调整写法,比如用嵌套指针或容器 // 示例调整方向:unsigned char*** frames = new unsigned char**[size]; // 再循环分配后续维度 if (!Buffer::time_codes || !Buffer::time_stamps) { std::cout << "Error allocating memory" << std::endl; exit(1); } }
方法2:转成std::tuple后用std::get
先把py::tuple转换成C++标准tuple,再用熟悉的std::get访问:
#include <tuple> Buffer::Buffer(int size, py::tuple hw_args_) { // C++17及以上可直接用结构化绑定 auto [frame_height, frame_width] = hw_args_.cast<std::tuple<unsigned int, unsigned int>>(); // C++17之前写法: // auto args_tuple = hw_args_.cast<std::tuple<unsigned int, unsigned int>>(); // unsigned int frame_height = std::get<0>(args_tuple); // unsigned int frame_width = std::get<1>(args_tuple); Buffer::time_codes = new int[size]; Buffer::time_stamps = new std::string[size]; if (!Buffer::time_codes || !Buffer::time_stamps) { std::cout << "Error allocating memory" << std::endl; exit(1); } }
额外提示
你代码里的三维数组分配new unsigned char[size][hw_args[0]][hw_args[1]]是无效C++语法——动态分配多维数组时,除第一维外,其他维度必须是编译期常量。建议改用嵌套指针或std::vector容器管理内存,避免内存泄漏和语法错误。
内容的提问来源于stack exchange,提问作者user1209675
相关产品推荐
相关产品推荐

