Wrapping a custom C ++ template class with swig

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

the difference between the two classes is the specification of the container followed by the vector container and the differrent signature of the value () method, where the first takes no arguments and the second takes the expected integer.

the shell code combined by swig wrapps, %template(FooVectorInt) incorrect, because it calls the value() method, and not the specialized vector method value(const int) . giving me the following compilation 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: TX::Foo<std::vector<_RealType> >::value(int) const [with T = int, int = unsigned int] 

Any tips on what I might lose in order to make swig understand which function is right?

amuses

+3
source share
1 answer

You can achieve the desired result:

 %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 is not C ++, and all that matters is that the SWIG code is generated with the correct code. If you want to repeat this lot, you can write macros (which is close to what %template is anyway).

However, this is not a very clean solution - I expected this to “just work” with the specializations, and I don't see a simpler workaround.

+2
source

Source: https://habr.com/ru/post/1244405/


All Articles