I am wanting to wrap std::set_intersection
, but I am getting confusing results.
Code to reproduce error:
%%cython -a -+
from libcpp.vector cimport vector
from libcpp.algorithm cimport set_intersection
from libcpp.iterator cimport back_inserter
cdef vector[int] x, y, z
cdef intersection(vector[int]* i1, vector[int]* i2, vector[int]* o):
set_intersection(i1.begin(), i1.end(), i2.begin(), i2.end(), back_inserter(o[0]))
x = [1, 2, 3]
y = [1, 3, 5]
intersection(&x, &y, &z)
print(z)
What I think intersection
should do:
Take three vector[int]
pointers and take the intersection of i1
and i2
and apply push_back
to o
the elements that are shared between i1
and i2
.
I get errors on compilation, however.
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\include\iterator(41): error C2825: '_Container': must be a class or namespace when followed by '::'
C:\Users\<redacted>\.ipython\cython\_cython_magic_0c03d6fb9770602e2805cbe448ec2c32fdd0e67d.cpp(2279): note: see reference to class template instantiation 'std::back_insert_iterator<std::vector<int,std::allocator<int>> &>' being compiled
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\include\iterator(41): error C2510: '_Container': left of '::' must be a class/struct/union
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\include\iterator(41): error C2182: '_Val': illegal use of type 'void'
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\include\iterator(46): error C2825: '_Container': must be a class or namespace when followed by '::'
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\include\iterator(46): error C2510: '_Container': left of '::' must be a class/struct/union
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\include\iterator(46): error C2182: '_Val': illegal use of type 'void'
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\include\iterator(64): error C2528: 'container': pointer to reference is illegal
If I modify the function a little bit by defining a vector in-scope, and copying the values it works just fine.
%%cython -a -+
from libcpp.vector cimport vector
from libcpp.algorithm cimport set_intersection
from libcpp.iterator cimport back_inserter
cdef vector[int] x, y, z
cdef intersection(vector[int]* i1, vector[int]* i2, vector[int]* o):
cdef vector[int] o2
set_intersection(i1.begin(), i1.end(), i2.begin(), i2.end(), back_inserter(o2))
o[0] = o2
x = [1, 2, 3]
y = [1, 3, 5]
intersection(&x, &y, &z)
print()
print(z)
results in
[1, 3]
But, obviously I would like the intersection to fill the appropriate container, and avoid the extra copying.
note: see reference to class template instantiation 'std::back_insert_iteratorstd::vector<int,std::allocator<int> &>' being compiled
Because std::back_insert_iterator
's template parameter is deduced to a reference which is wrong.
https://en.cppreference.com/w/cpp/iterator/back_insert_iterator
Instantiating it explicitly could solve the problem:
back_inserter[vector[int]](o[0])