Как выставить boost :: tuples :: tuple для привязок Java? - PullRequest
0 голосов
/ 12 марта 2012

У меня есть список boost::tuple.Я хочу представить этот список кортежей привязкам Java через SWIG.Но когда я пытаюсь скомпилировать mt wrap.cxx, сгенерированный SWIG, я получаю следующие ошибки:

d:\xyz\...\vector.h(115) : error C2678: binary '==' : no operator found which takes a left-hand operand of type 'const boost::tuples::tuple<T0,T1>' (or there is no acceptable conversion)
        with
        [
            T0=std::string,
            T1=std::string
        ]
        c:\program files\microsoft visual studio 8\vc\platformsdk\include\guiddef.h(192): or 'int operator ==(const GUID &,const GUID &)'
        while trying to match the argument list '(const boost::tuples::tuple<T0,T1>, const MyTuple)'
        with
        [
            T0=std::string,
            T1=std::string
        ]
        d:\xyz\...\vector.h(111) : while compiling class template member function 'int Vector<T>::index(const T &) const'
        with
        [
            T=MyTuple
        ]
        d:\xyz\...\MyTuple_wrap.cxx(17731) : see reference to class template instantiation 'Vector<T>' being compiled
        with
        [
            T=MyTuple
        ]

Может кто-нибудь сказать мне, что я должен сделать для решения этой проблемы?

1 Ответ

3 голосов
/ 07 октября 2012

Неясно, как вы пришли к ошибке, которую вы показали.boost::tuple сложно обернуть по умолчанию, и, кажется, нет никакого стандартного интерфейса к нему, включенного в SWIG.В моих тестах я не мог подобраться к ошибке, которую вы видели, без ручной записи файла интерфейса.

Однако мне удалось обернуть кортежи boost, используя следующий файл интерфейса:

%{
#include <boost/tuple/tuple.hpp>
%}

namespace boost {
  template <typename T1=void, typename T2=void, typename T3=void> 
  struct tuple;

  template <>
  struct tuple<void,void,void> {
  };

  template <typename T1>
  struct tuple<T1, void, void> {
    tuple(T1);
    %extend {
      T1 first() const {
        return boost::get<0>(*$self);
      }
    }
  };

  template <typename T1, typename T2>
  struct tuple <T1, T2, void> {
    tuple(T1,T2);
    %extend {
      T1 first() const {
        return boost::get<0>(*$self);
      }
      T2 second() const { 
        return boost::get<1>(*$self);
      }
    }
  };

  template <typename T1, typename T2, typename T3> 
  struct tuple <T1,T2,T3> {
    tuple(T1,T2,T3);
    %extend {
      T1 first() const {
        return boost::get<0>(*$self);
      }
      T2 second() const {
        return boost::get<1>(*$self);
      }
      T3 third() const {
        return boost::get<2>(*$self);
      }
    }
  };
}

В основном все, что он делает - это добавляет функции доступа к каждой из специализаций кортежа, которые могут вас заинтересовать.Достаточно сделать его минимально полезным на Java или другом языке.Вы хотели бы расширить это, чтобы охватить большие кортежи.Возможно, вы захотите заставить функции-члены получать / устанавливать, если ваши кортежи не предназначены для неизменности.

Я смог проверить это с помощью модуля SWIG:

%module test

%include "boost_tuple.i"

%template(TestTuple) boost::tuple<int, double, char>;

%template(SingleTuple) boost::tuple<char>;

%inline %{
boost::tuple<int, double, char> func1() {
  return boost::make_tuple(3, 2.0, '1');
}

void test1(boost::tuple<int, double, char>) {
}

%}

, который сработалкак и ожидалось со следующей Java:

public class run {
  public static void main(String[] argv) {
    System.loadLibrary("test");
    TestTuple t = test.func1();
    System.out.println("1: " + t.first() + " 2: " + t.second() + " 3: " + t.third());
    test.test1(test.func1());
    test.test1(new TestTuple(0, 0.0, '0'));
  }
}
...