почему Swig без проблем приводит python список к std :: vector, а не к std :: set? - PullRequest
0 голосов
/ 20 марта 2020

Я провожу некоторые испытания с помощью swig, чтобы расширить класс basi c C ++ до python. Я обнаружил поведение, связанное с использованием наборов, которое пока не могу объяснить. Вот мои сценарии:

MyClass.h:

#pragma once
#include <set>
#include <vector>

class MyClass
{
public:
    MyClass();
    void setSTLVector(const std::vector<int> &vector);
    void setSTLSet(const std::set<int> &set);

private:
    std::vector<int> _stlVector;
    std::set<int> _stlSet;
};

MyClass. cpp:

#include "MyClass.h"

MyClass::MyClass()
{
}

void MyClass::setSTLVector(const std::vector<int> &vector)
{
    _stlVector = vector;
}

void MyClass::setSTLSet(const std::set<int> &set)
{
    _stlSet = set;
}

MyClass.i:

%module MyClass

%{
    #include "MyClass.h"
%}

%include <typemaps.i>

%include "std_vector.i"
%template(IntVector) std::vector<int>;

%include "std_set.i"
%template(IntSet) std::set<int>;

%include "MyClass.h"

при компиляции все (кажется) ОК. Мое недоразумение начинается с запуска моего расширения в python. Действительно:

In [1]: import MyClass
In [2]: cls = MyClass.MyClass()
In [3]: cls.setSTLVector([1,2,3,4])

отлично работает, по крайней мере, так, как я ожидаю, то есть python list of integers преобразуется внутренне в std::vector<int>. Для набора:

In [1]: import MyClass
In [2]: cls = MyClass.MyClass()
In [3]: cls.setSTLVector({1,2,3,4})

вызывает следующую ошибку:

TypeError: in method 'MyClass_setSTLSet', argument 2 of type 'std::set< int,std::less< int >,std::allocator< int > > const &'

Эта ошибка, вероятно, связана с другой, которую я имею, когда я объявляю набор, используя тип, определенный в swig:

In [1]: import MyClass
In [2]: cls = MyClass.IntSet({1,2,3,4})

, что дает:

NotImplementedError: Wrong number or type of arguments for overloaded function 'new_IntSet'.
  Possible C/C++ prototypes are:
    std::set< int >::set(std::less< int > const &)
    std::set< int >::set()
    std::set< int >::set(std::set< int > const &)

Не могли бы вы знать, что я делаю неправильно, или это нормальное поведение?

1 Ответ

1 голос
/ 23 марта 2020

Карты типов для std_set.i неинтуитивно ожидают Python list в качестве ввода, а не set.

>>> import MyClass
>>> cls = MyClass.MyClass()
>>> cls.setSTLVector([1,2,3,4]) # works
>>> cls.setSTLSet([1,2,3,4])    # works
>>> cls.setSTLSet({1,2,3,4})    # doesn't work
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\MyClass.py", line 385, in setSTLSet
    return _MyClass.MyClass_setSTLSet(self, set)
TypeError: in method 'MyClass_setSTLSet', argument 2 of type 'std::set< int,std::less< int >,std::allocator< int > > const &'**strong text**

Вы должны будете определить свою собственную карту типов, чтобы принять set в качестве ввода.

...