关于c ++:Boost Python使用默认参数包装静态成员函数重载

Boost Python wrap static member function overload with default argument

我有Python的附加C++包装示例:成员函数(方法)是静态的,带有默认参数。所以我使用boost_python_成员_函数_重载来定义重载函数。没有编译错误,但是当我调用静态成员函数时,得到如下错误:

1
2
import boostPythonTest    
boostPythonTest.C.method("string")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
---------------------------------------------------------------------------  ArgumentError Traceback (most recent call last)
<ipython-input-4-ab141804179c> in <module>()
----> 1 boostPythonTest.C.method("string")

ArgumentError: Python argument types in
C.method(str) did not match C++ signature:

method(class C {lvalue}, class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> >)

method(class C {lvalue}, class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> >, int)

method(class C {lvalue}, class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> >, int, bool)

我不明白为什么第一个生成的签名是"class c lvalue"。如果是这样,静态成员函数需要调用C的一个实例,那么对我来说,它看起来是矛盾的。

另一方面,我在不使用成员函数重载的情况下定义了另一个静态成员函数,它不使用"class c lvalue"签名。例如:

1
boostPythonTest.C.noDefaultArgMethod("string", 0, True)

Type: function String Form: Docstring: noDefaultArgMethod( (str)arg1, (int)arg2,
(bool)arg3) -> int :

1
2
C++ signature :
    int noDefaultArgMethod(

class std::basic_string,class
std::allocator >, int, bool)

有没有人能解释一下boost_python_member_function_重载的问题,或者给出一些建议,如何将其作为真正的静态成员函数来使用重载?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/args.hpp>
#include <boost/python/tuple.hpp>
#include <boost/python/class.hpp>
#include <boost/python/overloads.hpp>
#include <boost/python/return_internal_reference.hpp>
#include <boost/python/register_ptr_to_python.hpp>
#include <boost/python/object/class.hpp>

using namespace boost::python;

class C {
public:
    static int method(const std::string &arg1, int arg2 = 0, bool arg3 = true) {
        return 1;
    };

    static int noDefaultArgMethod(const std::string &arg1, int arg2 = 0, bool arg3 = true) {
        return 10;
    };

};

BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(method1, C::method, 1, 3)

BOOST_PYTHON_MODULE(boostPythonTest)
{

    class_<C>("C")
        .def("method", (int(C::*)(const std::string&, int, bool))0, method1())
        .staticmethod("method")
        .def("noDefaultArgMethod", &C::noDefaultArgMethod)
        .staticmethod("noDefaultArgMethod");

}

我相信这句话:

1
.def("method", (int(C::*)(const std::string&, int, bool))0, method1())

应该如下所示:

1
.def("method", &C::method, method1())

您应该使用BOOST_PYTHON_FUNCTION_OVERLOADS而不是BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS,因为没有涉及C对象(静态函数指针只是函数指针,它们不是指向成员的指针)。

在这个wiki上还发布了一个带有重载静态函数的示例,其中相关部分是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class X {
    static int returnsum(int m, int x = 10) { return m + x; }
};

BOOST_PYTHON_FUNCTION_OVERLOADS(X_returnsum_overloads, X::returnsum, 1, 2)

BOOST_PYTHON_MODULE(foo)
{
    class_<X>("X", ..)
        .def("returnsum", &X::returnsum,
            X_returnsum_overloads(args("x","m"),"returnsum's docstring")
            )
        .staticmethod("returnsum")
        ;
}

这似乎正是你想要的。