用swig包装专门的c++模板类

wrapping specialised c++ template class with swig

本文关键字:c++ swig 包装      更新时间:2023-10-16

考虑以下类声明:

namespace X {
template<class T>
class Foo {
public:
    Foo();
    virtual ~Foo();
    T value() const;
};
template<class T>
class Foo<vector<T>> {
public:
    Foo();
    virtual ~Foo();
    T value( const int ) const;
};
}

对于它们,我在foo.i文件中有以下声明

%include "stl.i"
%include "std_string.i"
%include "std_vector.i"
namespace X {
using namespace std;
template<class T>
class Foo {
public:
    Foo();
    virtual ~Foo();
    T value() const;
};
template<class T>
class Foo<vector<T> > {
public:
    Foo();
    virtual ~Foo();
    T value( const int ) const;
};
%template(FooInt) Foo<int>;
%template(FooString) Foo<string>;
%template(FooVectorInt) Foo<vector<int> >;
}

这两个类之间的区别在于后向向量容器value()方法的differential签名的特殊化,其中第一个不带参数,而第二个带一个期望的整数。

swig组合的包装器代码错误地包装了%template(FooVectorInt),因为它调用value()方法而不是专门的向量方法value(const int)。给我以下编译错误消息:

foo_wrap.cxx: in function »int _wrap_FooVectorInt_value(lua_State*)«:
/home/noobsaibot/foo/bindings/src/lua/foo_wrap.cxx:6706:81: error: no matching function to call »X::Foo<std::vector<int> >::value() const«
/home/noobsaibot/foo/src/foo.h:78:5: note: candidate is: T X::Foo<std::vector<_RealType> >::value(int) const [with T = int, int = unsigned int]

有什么建议可以让swig了解哪种功能是正确的吗?

欢呼

您可以通过执行以下操作来实现您想要的结果:

%include "stl.i"
%include "std_string.i"
%include "std_vector.i"
namespace X {
using namespace std;
%rename(FooVectorInt) Foo<std::vector<int> >;
class Foo<std::vector<int> > {
public:
    virtual ~Foo();
    int value( const int ) const;
};
template<class T>
class Foo {
public:
    Foo();
    virtual ~Foo();
    T value() const;
};
%template(FooInt) Foo<int>;
%template(FooString) Foo<string>;
}

这之所以有效,是因为您在接口文件中编写的不是C++,重要的是SWIG生成了正确的代码。如果你想重复这些,你可以写宏(无论如何,这接近于%template)。

尽管如此,这并不是一个非常干净的解决方案——我预计这将"只适用于"专业领域,我也看不到更简单的解决方案。