且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

用Swig包装专用的c ++模板类

更新时间:2022-10-15 15:15:24

您可以通过执行以下操作来获得所需的结果:

 %include stl.i  
%include std_string.i
%include std_vector.i

命名空间X {
使用命名空间std;

%rename(FooVectorInt)Foo< std :: vector< int> &gt ;;

类Foo< std :: vector< int> > {
public:
virtual〜Foo();
int value(const int)const;
};

template< class T>
Foo类{
public:
Foo();
虚拟〜Foo();
T value()const;
};

%template(FooInt)Foo< int&gt ;;
%template(FooString)Foo< string&gt ;;
}

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



这仍然不是一个很干净的解决方案-我希望它可以与专业化结合使用,而且我也看不到任何更简单的解决方法。

consider the following class declarations:

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;
};
}

for them i have the following declaration in the foo.i file

%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> >;

}

the difference between the two classes is the specialisation of the later to vector container and the differrent signature of the value() method, where the first takes no arguments, while the second takes an expects an integer.

the wrapper code put together by swig wrapps the %template(FooVectorInt) wrong, in that it calls the value() method instead that of the specialised vector method value(const int). giving me the following compile error message:

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]

any advices as to what i might be missing to make swig understand which function is the correct one?

cheers

You can achieve the result you want by doing:

%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>;
}

This works because what you write in the interface file isn't C++ and all that matters is that the correct code is generated by SWIG. If you want to repeat this lots you can write macros (which is close to what %template is anyway).

Still this isn't a very clean solution - I expected this to "just work" with the specialisations and I can't see a simpler workaround either.