无法在 pybind11 中绑定重载的静态成员函数
Unable to bind overloaded static member functions in pybind11
我尝试用 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));
仅供参考 - 首先,C++ 标准草案 n3337(本质上是 C++11)的 8.3.1 指针 [dcl.ptr] / 1州
In a declaration T D where D has the form
* attribute-specifier-seq cv-qualifier-seq D1
and the type of the identifier in the declaration T D1 is “derived-declarator-type-list T,” then the type of the identifier of D is “derived-declarator-type-list cv-qualifier-seq pointer to T.” ...
和8.3.3指向成员的指针[dcl.mptr] / 1状态
In a declaration T D where D has the form
nested-name-specifier * attribute-specifier-seq cv-qualifier-seq D1
and the nested-name-specifier denotes a class, and the type of the identifier in the declaration T D1 is “derived-declarator-type-list T”, then the type of the identifier of D is “derived-declarator-type-list cv-qualifier-seq pointer to member of class nested-name-specifier of type T”. ...
这些语句意味着当且仅当函数 TESTDB::aaaa
是一个成员函数 .
接下来,5.2.2 函数调用[expr.call]状态
- There are two kinds of function call: ordinary function call and member function63 (9.3) call. ...
其中脚注63是
63) A static member function (9.4) is an ordinary function.
这意味着你的静态成员函数TESTDB::aaaa
是一个普通函数,而不是成员函数。
因此,您不得在当前演员表中指定 TESTDB::
。
总而言之,您必须像这样消除 TESTDB::aaaa
的两个重载的歧义:
static_cast<void (*)(int, int)>(&TESTDB::aaaa)
我尝试用 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));
仅供参考 - 首先,C++ 标准草案 n3337(本质上是 C++11)的 8.3.1 指针 [dcl.ptr] / 1州
In a declaration T D where D has the form
* attribute-specifier-seq cv-qualifier-seq D1
and the type of the identifier in the declaration T D1 is “derived-declarator-type-list T,” then the type of the identifier of D is “derived-declarator-type-list cv-qualifier-seq pointer to T.” ...
和8.3.3指向成员的指针[dcl.mptr] / 1状态
In a declaration T D where D has the form
nested-name-specifier * attribute-specifier-seq cv-qualifier-seq D1
and the nested-name-specifier denotes a class, and the type of the identifier in the declaration T D1 is “derived-declarator-type-list T”, then the type of the identifier of D is “derived-declarator-type-list cv-qualifier-seq pointer to member of class nested-name-specifier of type T”. ...
这些语句意味着当且仅当函数 TESTDB::aaaa
是一个成员函数 .
接下来,5.2.2 函数调用[expr.call]状态
- There are two kinds of function call: ordinary function call and member function63 (9.3) call. ...
其中脚注63是
63) A static member function (9.4) is an ordinary function.
这意味着你的静态成员函数TESTDB::aaaa
是一个普通函数,而不是成员函数。
因此,您不得在当前演员表中指定 TESTDB::
。
总而言之,您必须像这样消除 TESTDB::aaaa
的两个重载的歧义:
static_cast<void (*)(int, int)>(&TESTDB::aaaa)