如何在nanobind中导出类的成员的成员(无需lambda)
问题
给定以下C++结构体:
struct A { int member; }; struct B { A a; };
使用nanobind时,通过lambda表达式可以成功导出B中嵌套的a.member:
NB_MODULE(foo, m) { nanobind::class_<B>(m, "B") .def(nanobind::init<>()) .def("member_of_a", [](B &b) -> int { return b.a.member; }); }
但尝试直接使用&B::a.member的写法会编译失败:
NB_MODULE(foo, m) { nanobind::class_<B>(m, "B") .def(nanobind::init<>()) .def("member_of_a", &B::a.member); // 编译失败 }
求不使用lambda的可行实现方式。
解决方案
C++语法不支持直接获取嵌套成员的指针(&B::a.member本身就是非法写法),但可以通过以下方式实现无lambda的绑定:
方式1:添加成员函数包装
给B新增一个成员函数,用于返回嵌套的member值:
struct B { A a; int get_member_of_a() { return a.member; } };
随后直接绑定这个成员函数即可:
NB_MODULE(foo, m) { nanobind::class_<B>(m, "B") .def(nanobind::init<>()) .def("member_of_a", &B::get_member_of_a); }
如果需要支持修改,还可以新增setter函数并绑定:
struct B { A a; int get_member_of_a() { return a.member; } void set_member_of_a(int val) { a.member = val; } }; NB_MODULE(foo, m) { nanobind::class_<B>(m, "B") .def(nanobind::init<>()) .def("get_member_of_a", &B::get_member_of_a) .def("set_member_of_a", &B::set_member_of_a); }
方式2:使用标准库绑定器组合成员指针
可以结合std::mem_fn和std::bind来组合两层成员指针,避免手动编写lambda:
#include <functional> NB_MODULE(foo, m) { using namespace std::placeholders; auto getter = std::bind(&A::member, std::bind(&B::a, _1)); nanobind::class_<B>(m, "B") .def(nanobind::init<>()) .def("member_of_a", getter); }
核心原因
C++中,成员指针只能指向结构体的直接成员,无法跨层级指向嵌套成员,因此必须通过一层包装(成员函数、标准库绑定器等)来间接访问嵌套的a.member。
内容的提问来源于stack exchange,提问作者Konstante
相关产品推荐
相关产品推荐

