overloading - pybind11 带有“auto”关键字的重载函数
问题描述
我想帮助包装一个使用“auto”返回类型的重载函数。例如,https://github.com/microsoft/SEAL/blob/master/native/src/seal/ciphertext.h中第 699 行和第 708 行的函数
SEAL_NODISCARD inline auto &scale() noexcept
{
return scale_;
}
SEAL_NODISCARD inline auto &scale() const noexcept
{
return scale_;
}
当我尝试如下绑定时,
py::class_<Ciphertext>(m, "Ciphertext")
.def("scale", (auto (Ciphertext::*)() const)&Ciphertext::scale, "returns a constant reference to the scale")
我看到这个错误
...mseal.cpp:223:18: error: invalid use of ‘auto’
.def("scale", (auto (Ciphertext::*)() const)&Ciphertext::scale, "returns a constant reference to the scale")
我正在使用 C++17 和 python3。我不想修改 C++ SEAL 库。谢谢你。
解决方案
编辑:我刚刚发现 pybind11 有一个辅助构造来做同样的事情,从而导致更简单/更清洁的代码。PYBIND11_MODULE
将原始答案中的块替换为:
PYBIND11_MODULE(mseal, m) {
py::class_<Ciphertext>(m, "Ciphertext")
.def(py::init<>())
.def("scale",
py::overload_cast<>(&Ciphertext::scale, py::const_),
"returns a constant reference to the scale")
.def("scale_nonconst",
py::overload_cast<>(&Ciphertext::scale),
"returns a reference to the scale");
}
原始答案:您需要decltype
获取返回类型并std::declval
消除decltype
. 下面是一个完整的工作示例(最低 C++14),我在其中添加了非常量版本,只是为了表明您可以完全控制以下任一选项的选择:
#include <pybind11/pybind11.h>
#include <pybind11/pytypes.h>
#include <iostream>
#include <utility>
namespace py = pybind11;
class Ciphertext {
public:
inline auto &scale() noexcept {
std::cerr << "non-const called" << std::endl;
return scale_;
}
inline auto &scale() const noexcept {
std::cerr << "const called" << std::endl;
return scale_;
}
private:
int scale_;
};
PYBIND11_MODULE(mseal, m) {
py::class_<Ciphertext>(m, "Ciphertext")
.def(py::init<>())
.def("scale",
static_cast<decltype(std::declval<Ciphertext const&>().scale()) (Ciphertext::*)() const>(&Ciphertext::scale),
"returns a constant reference to the scale")
.def("scale_nonconst",
static_cast<decltype(std::declval<Ciphertext&>().scale()) (Ciphertext::*)()>(&Ciphertext::scale),
"returns a reference to the scale");
}
其中,当编译成mseal.so
预期的作品时:
>>> import mseal
>>> mseal.Ciphertext().scale()
const called
0
>>> mseal.Ciphertext().scale_nonconst()
non-const called
0
>>>
推荐阅读
- html - 纯 CSS:从上到下截断多个段落的文本溢出
- javascript - MATERIAL-UI:未捕获的 ReferenceError:未定义 createSvgIcon
- python - Tensorflow 2x:参数 include_optimizer 究竟对 tensorflow.keras.save_model 有什么影响
- c# - 上传图片并在 asp.net core mvc 中显示
- flutter - “Widget”类型的值不能分配给“PreferredSizeWidget”类型的变量
- php - 从不同的记录更新产品表数量
- reactjs - 如何解决 Next.js 中的“未定义窗口”错误
- python - 将嵌套字典减少为“top-key-root-element”字典
- node.js - 节点窗口不卸载节点服务
- java - readLine() 使用 Socket 阻塞