使用SWIG封装特定的C++模板类

5

考虑以下类声明:

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()方法的签名不同,其中第一个不带参数,而第二个则需要一个整数作为参数。
由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理解哪个函数是正确的?谢谢。
1个回答

4
你可以通过以下方式达到你想要的结果:
%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很接近)。

然而,这并不是一个非常干净的解决方案 - 我本来期望通过特化来实现这一点,并且我也看不到更简单的解决方法。


忘记我写的,我没有得到错误。现在开始检查它是否做了它应该做的事情 :) ... 到目前为止谢谢。 - noobsaibot
它编译成功并返回了“正确”的对象Foo<vector<int>>,但是Lua不知道这种类型...导致该对象在Lua中无法使用 :/ ... - noobsaibot
@noobsaibot - 你说的“not known to lua”是什么意思?在我进行的Python测试中,它看起来已经被正确地注册了。(我从未使用过lua) - Flexo
没关系,我已经重构了我的代码,使得基于集合的类与简单类有不同的名称。问题解决了 :) - noobsaibot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接