【问题标题】:Unable to bind overloaded static member functions in pybind11无法在 pybind11 中绑定重载的静态成员函数
【发布时间】:2019-08-31 23:20:51
【问题描述】:

我尝试用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");};

有什么想法吗?

谢谢

【问题讨论】:

    标签: python c++ function-pointers member-function-pointers pybind11


    【解决方案1】:

    问题是你的演员(void (TESTDB::*)(int, int))。该强制转换是将指向静态成员函数的指针转换为指向 non 静态成员函数的指针,这是不正确的。

    由于函数是静态的,你应该简单地将它们转换为指向普通非成员函数的指针:

    py::class_<TESTDB>(m, "db")
        .def_static("aaaa", static_cast<void (*)(int, int)>(&TESTDB::aaaa));
    

    【讨论】:

    • 强制性“另一个例子,static_cast 让你走在正确的轨道上,不像 C 风格的演员表”。
    • 太棒了。你能详细说明一下“*”符号吗?
    • @alec.tu 这与您在问题中显示的演员表的含义完全相同:它表示 pointer
    • @alec.tu void (*)(int, int) 类型的意思是“指向带有两个 int 参数的函数的指针,不返回任何内容”。 void (TESTDB::*)(int, int) 类型的意思是“指向 TESTDB 成员函数的指针,带有两个 int 参数,不返回任何内容”。
    【解决方案2】:

    仅供参考 - 首先,C++ 标准草案 n3337(本质上是 C++11)的 8.3.1 指针 [dcl.ptr] / 1 声明

    在声明 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 指向类成员的指针 nested-name-specifier T 型”。 ...

    这些语句意味着我们必须在 TESTDB::* 中使用上述 nested-name-specifier TESTDB:: 当且仅当函数 TESTDB::aaaa 是成员函数时强>.

    接下来,5.2.2 函数调用[expr.call]状态

    1. 函数调用有两种:普通函数调用和成员函数63(9.3)调用. ...

    脚注63在哪里

    63) 静态成员函数 (9.4) 是一个普通函数

    这意味着您的静态成员函数TESTDB::aaaa普通函数,而不是成员函数。 因此,您不能在当前演员表中指定TESTDB::


    总而言之,您必须像这样消除TESTDB::aaaa 的两个重载的歧义:

    Live DEMO

    static_cast<void (*)(int, int)>(&TESTDB::aaaa)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-29
      • 1970-01-01
      • 1970-01-01
      • 2013-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多