消除非常量和常量访问方法的歧义 (Pybind11)
Disambiguate non-const and const access methods (Pybind11)
我正在尝试使用 Pybind11 包装一些 C++ class。
class (Alpha) 两个 getter,一个返回对成员的 const 引用 force_
另一个返回非常量引用。
struct Dummy {
double x{3.3};
};
class Alpha {
const Dummy& force() const {return force_;}
Dummy& force() {return force_;}
private:
Dummy force_;
};
我最初尝试使用 py::return_value_policy
但是这样,似乎我没有正确区分函数 force()
的两个版本之间的歧义,因为我得到
note: template argument deduction/substitution failed:
和 couldn’t deduce template parameter ‘Func’
py::class_<Alpha>(m, "Alpha")
.def(py::init())
.def("force", &Alpha::force, "returns reference", py::return_value_policy::reference_internal)
.def("force", &Alpha::force, "returns copy", py::return_value_policy::copy);
}
我是不是走错了方向?我真的不想改变代码的 C++ 端。一个附带的问题是:我怎么能明确地写 &Alpha::force
来表示 const 或非 const 版本。
我不知道 pybind,但我想 Func
是 def
试图从其第二个参数推导出来的类型。问题是您无法获得指向重载集的函数指针。您只能获取指向单个函数的函数指针。
The documentation states that Func can be a plain C++ function, a function pointer, or a lambda function
好的,但不能是一整套重载!
这就是为什么您的 class(我必须制作 force
public!),出于同样的原因,这将不起作用:
int main() {
auto x = &Alpha::force;
}
产生的错误是:
<source>:15:10: error: variable 'x' with type 'auto' has incompatible initializer of type '<overloaded function type>'
auto x = &Alpha::force;
^ ~~~~~~~~~~~~~
无法单独从 &Alpha::force
推断出类型。
您可以通过 static_cast
:
从超载集中选择一个
auto x = static_cast< const Dummy& (Alpha::*)() const>(&Alpha::force);
与非常量类似:
auto y = static_cast< Dummy& (Alpha::*)()>(&Alpha::force);
PS:您引用的文档实际上没有提到成员函数。我想那是由于引用不完整。如果 def
不能接受成员函数指针,您必须将 force
设为静态,或者将调用包装在自由函数/lambda 中。不要忘记指向成员函数的指针与指向自由函数的指针有根本的不同(它们需要一个对象才能被调用)。
我正在尝试使用 Pybind11 包装一些 C++ class。
class (Alpha) 两个 getter,一个返回对成员的 const 引用 force_
另一个返回非常量引用。
struct Dummy {
double x{3.3};
};
class Alpha {
const Dummy& force() const {return force_;}
Dummy& force() {return force_;}
private:
Dummy force_;
};
我最初尝试使用 py::return_value_policy
但是这样,似乎我没有正确区分函数 force()
的两个版本之间的歧义,因为我得到
note: template argument deduction/substitution failed:
和 couldn’t deduce template parameter ‘Func’
py::class_<Alpha>(m, "Alpha")
.def(py::init())
.def("force", &Alpha::force, "returns reference", py::return_value_policy::reference_internal)
.def("force", &Alpha::force, "returns copy", py::return_value_policy::copy);
}
我是不是走错了方向?我真的不想改变代码的 C++ 端。一个附带的问题是:我怎么能明确地写 &Alpha::force
来表示 const 或非 const 版本。
我不知道 pybind,但我想 Func
是 def
试图从其第二个参数推导出来的类型。问题是您无法获得指向重载集的函数指针。您只能获取指向单个函数的函数指针。
The documentation states that Func can be a plain C++ function, a function pointer, or a lambda function
好的,但不能是一整套重载!
这就是为什么您的 class(我必须制作 force
public!),出于同样的原因,这将不起作用:
int main() {
auto x = &Alpha::force;
}
产生的错误是:
<source>:15:10: error: variable 'x' with type 'auto' has incompatible initializer of type '<overloaded function type>'
auto x = &Alpha::force;
^ ~~~~~~~~~~~~~
无法单独从 &Alpha::force
推断出类型。
您可以通过 static_cast
:
auto x = static_cast< const Dummy& (Alpha::*)() const>(&Alpha::force);
与非常量类似:
auto y = static_cast< Dummy& (Alpha::*)()>(&Alpha::force);
PS:您引用的文档实际上没有提到成员函数。我想那是由于引用不完整。如果 def
不能接受成员函数指针,您必须将 force
设为静态,或者将调用包装在自由函数/lambda 中。不要忘记指向成员函数的指针与指向自由函数的指针有根本的不同(它们需要一个对象才能被调用)。