我试图用pybind11绑定静态重载函数,但遇到了一些问题。
这是示例代码
#include <pybind11/pybind11.h>
namespace py = pybind11;
class TESTDB {
public:
static void aaaa(int a, int b) {printf("aaaaa");};
static void aaaa(int a) {printf("xxxxx");};
};
PYBIND11_MODULE(example, m) {
py::class_<TESTDB>(m, "db")
.def_static("aaaa", (void (TESTDB::*)(int, int)) &TESTDB::aaaa);
}
但由于这个原因无法编译
error: no matches converting function ‘aaaa’ to type ‘void (class TESTDB::*)(int, int)’
.def_static("aaaa", (void (TESTDB::*)(int, int)) &TESTDB::aaaa);
note: candidates are: static void TESTDB::aaaa(int)
static void aaaa(int a) {printf("xxxxx");};
note: static void TESTDB::aaaa(int, int)
static void aaaa(int a, int b) {printf("aaaaa");};
任何的想法?
谢谢
问题是你的演员(void (TESTDB::*)(int, int))
。该转换是将指向静态成员函数的指针转换为指向非静态成员函数的指针,这是不正确的。
由于函数是静态的,您应该简单地将它们作为指向普通非成员函数的指针:
py::class_<TESTDB>(m, "db")
.def_static("aaaa", static_cast<void (*)(int, int)>(&TESTDB::aaaa));
仅供参考 - 首先,8.3.1指针[dcl.ptr] / 1的C ++标准草案n3337(主要是C ++ 11)声明
在声明T D中,D表示形式
* attribute-specifier-seq cv-qualifier-seq D1
并且声明T D1中的标识符的类型是“derived-declarator-type-list T”,然后D的标识符的类型是“derived-declarator-type-list cv-qualifier-seq指向T的指针”。 ...
和8.3.3指向成员的指针[dcl.mptr] / 1州
在声明T D中,D表示形式
nested-name-specifier * attribute-specifier-seq cv-qualifier-seq D1
并且nested-name-specifier表示一个类,并且声明T D1中的标识符的类型是“derived-declarator-type-list T”,然后D的标识符的类型是“derived-declarator-type-” list cv-qualifier-seq指向类型为T“的类nested-name-specifier成员的指针。 ...
这些语句意味着当且仅当函数TESTDB::
是成员函数时,我们必须在TESTDB::*
中使用上面的嵌套名称说明符TESTDB::aaaa
。
接下来,5.2.2函数调用[expr.call]指出
- 函数调用有两种:普通函数调用和成员函数63(9.3)调用。 ...
脚注63是哪里
63)静态成员函数(9.4)是普通函数。
这意味着您的静态成员函数TESTDB::aaaa
是普通函数,而不是成员函数。因此,您不能在当前演员表中指定TESTDB::
。
总之,你必须消除TESTDB::aaaa
的两个重载的歧义:
static_cast<void (*)(int, int)>(&TESTDB::aaaa)