обертывание специализированного шаблона класса C ++ с помощью Swig - PullRequest
5 голосов
/ 18 марта 2012

рассмотрим следующие объявления классов:

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 голосов
/ 19 марта 2012

Вы можете достичь желаемого результата, выполнив:

%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).

Тем не менее, это не очень чистое решение - я ожидал, что это "просто сработает" со специализациями, и я не вижу более простого обходного пути.

...