Python Swigging作为模板函数的类成员函数

Python Swigging作为模板函数的类成员函数,python,c++,swig,Python,C++,Swig,此问题基于以下问题: 然而,与这个问题相比,我试图包装的代码有点不同: class MyClass { public: template <class T> void f1(const string& firstArg, const T& value); }; 此接口要求Python客户端了解所有不同的f1函数名,每个函数名根据类型而有所不同。不太干净 可以通过重载、在接口文件中扩展来获得更干净的接口,例如 %extend MyClass {

此问题基于以下问题:

然而,与这个问题相比,我试图包装的代码有点不同:

class MyClass {
  public:
    template <class T>
     void f1(const string& firstArg, const T& value);
};
此接口要求Python客户端了解所有不同的f1函数名,每个函数名根据类型而有所不同。不太干净

可以通过重载、在接口文件中扩展来获得更干净的接口,例如

%extend MyClass {
   void f1(const string& s, const string& s1){
          $self->f1(s, s1);
   }
   void f1(const string& s, const int& anInt){
          $self->f1(s, anInt);
   }
}
这允许客户端代码如下所示:

o = MyClass
str1 = "A String"
anInt = 34
o.f1("", str1)
o.f1("", anInt)

问题是,有没有办法(通过扩展)获得上面的接口,而不用使用Swig进行扩展?

幸运的是,Python包装器支持重载,因此您可以简单地用相同的名称实例化这两个方法,Swig将在运行时发挥神奇的作用来解决重载问题。请参阅“SWIG和C++”章节中的更多细节。
测试.i

%module example
%{
#include<iostream>

class MyClass {
public:
    template <class T>
    void f1(const std::string& firstArg, const T& value) {
        std::cout << firstArg << ',' << value << '\n';
    }
};
%}

%include <std_string.i>

class MyClass {
public:
    template <class T>
    void f1(const std::string& firstArg, const T& value);
};

%extend MyClass {
    %template(f1) f1<std::string>;
    %template(f1) f1<int>;
}
要编译和运行的工作流示例:

$swig-python-c++test.i
$g++-Wall-Wextra-Wpedantic-I/usr/include/python2.7/-fPIC-sharedtest\u wrap.cxx-o\u example.so-lpython2.7
$python2.7 test.py
十、 一串
Y、 三十四

幸运的是,Python包装器支持重载,因此您可以简单地用相同的名称实例化这两个方法,SWIG将在运行时发挥其魔力来解决重载问题。请参阅“SWIG和C++”章节中的更多细节。
测试.i

%module example
%{
#include<iostream>

class MyClass {
public:
    template <class T>
    void f1(const std::string& firstArg, const T& value) {
        std::cout << firstArg << ',' << value << '\n';
    }
};
%}

%include <std_string.i>

class MyClass {
public:
    template <class T>
    void f1(const std::string& firstArg, const T& value);
};

%extend MyClass {
    %template(f1) f1<std::string>;
    %template(f1) f1<int>;
}
要编译和运行的工作流示例:

$swig-python-c++test.i
$g++-Wall-Wextra-Wpedantic-I/usr/include/python2.7/-fPIC-sharedtest\u wrap.cxx-o\u example.so-lpython2.7
$python2.7 test.py
十、 一串
Y、 三十四

能否显示实际输出,而不仅仅是“I get Type error”?此外,如果怀疑非模板参数是问题所在,为什么不测试它?临时添加一个
模板void f2(常数T和值)
%模板(f2String)MyClass::f2并查看是否有效。如果不是,你可以排除这种可能性,而不是仅仅猜测。等等,你刚才问的错误发生了什么?这似乎是一个与一分钟前完全不同的问题。我最初的问题在T论证中有一个问题,不是一个参考。我删除了它,所以代码编译得很好。问题是如何获得更干净的界面。抱歉搞混了,阿巴内特!你能显示实际的输出而不是“I get Type error”吗?另外,如果你怀疑非模板参数是问题所在,为什么不测试它呢?临时添加一个
模板void f2(常数T和值)
%模板(f2String)MyClass::f2并查看是否有效。如果不是,你可以排除这种可能性,而不是仅仅猜测。等等,你刚才问的错误发生了什么?这似乎是一个与一分钟前完全不同的问题。我最初的问题在T论证中有一个问题,不是一个参考。我删除了它,所以代码编译得很好。问题是如何获得更干净的界面。抱歉搞混了,阿巴内特!那确实很优雅!那确实很优雅!
%module example
%{
#include<iostream>

class MyClass {
public:
    template <class T>
    void f1(const std::string& firstArg, const T& value) {
        std::cout << firstArg << ',' << value << '\n';
    }
};
%}

%include <std_string.i>

class MyClass {
public:
    template <class T>
    void f1(const std::string& firstArg, const T& value);
};

%extend MyClass {
    %template(f1) f1<std::string>;
    %template(f1) f1<int>;
}