python - 简化在 Pybind11 中为 C++ 模板类生成包装类:模板声明不能出现在块范围内
问题描述
我正在尝试简化在 Pybind11 中为 C++ 模板类生成包装器类。这是一个显示问题的最小示例(遵循此答案):
#include <pybind11/pybind11.h>
#include <iostream>
namespace py = pybind11;
template<class T>
class Foo {
public:
Foo(T bar) : bar_(bar) {}
void print() {
std::cout << "Type id: " << typeid(T).name() << '\n';
}
private:
T bar_;
};
PYBIND11_MODULE(example, m) {
template<typename T>
void declare_foo(py::module &m, std::string &typestr) {
using Class = Foo<T>;
std::string pyclass_name = std::string("Foo") + typestr;
py::class_<Class>(m, pyclass_name.c_str())
.def(py::init< T >())
.def("print", &Class::print);
}
declare_foo<int>(m, "Int");
declare_foo<double>(m, "Double");
# More similar declarations follow here...
}
当我编译它时:
g++ -O3 -Wall -shared -std=c++17 -fPIC `python3 -m pybind11 --includes` example.cpp -o example`python3-config --extension-suffix`
我得到错误:
example.cpp: In function ‘void pybind11_init_example(pybind11::module&)’:
example.cpp:18:5: error: a template declaration cannot appear at block scope
18 | template<typename T>
| ^~~~~~~~
解决方案
就像错误表明您不能在块范围内有模板声明(您显然在一个https://en.cppreference.com/w/cpp/language/scope中)。只需将其移出并通过 const 引用(或值)捕获字符串参数。
将代码更改为
template<typename T>
void declare_foo(py::module &m, const std::string &typestr) {
using Class = Foo<T>;
std::string pyclass_name = std::string("Foo") + typestr;
py::class_<Class>(m, pyclass_name.c_str())
.def(py::init< T >())
.def("print", &Class::print);
}
PYBIND11_MODULE(example, m) {
declare_foo<int>(m, "Int");
declare_foo<double>(m, "Double");
}
作品。
作为旁注,您还应该
#include <string>
不建议依赖传递包含。
推荐阅读
- c - 间接“调用”指令是否总是指向函数序言?
- matlab - 可写逗号而不是点,用于小数点分隔符
- c - JSON序列化到缓冲区(C语言)
- java - Spring Cloud - Redis 速率限制 - 不适用于每分钟的请求
- esp32 - ESP32 Freertos:SPI 任务阻止其他任务(即使在不同的内核上!!)
- delphi - 如何为我的应用程序取消注册文件格式?
- android - Android 如何打开一个基于 Intent 的 Chrome URI
- javascript - 基于其他 div 内容的 Javascript 条件显示/隐藏 div
- php - 如何在 ubuntu 服务器中将 php 8.0 设置为默认版本
- django - django和pytest,多个数据库,只用一个数据库