# vector.pyxfrom libcpp.vector cimport vectorcdef class A:cdef int xcdef vector[A] vect
Error compiling Cython file:------------------------------------------------------------...from libcpp.vector cimport vectorcdef class A:cdef int xcdef vector[A] vect^------------------------------------------------------------vector.pyx:6:12: Python object type 'A' cannot be used as a template argument
Hi Stefan,Thanks for your reply.I think I see your point - though I am a total Cython newbie so I definitely need to think about it a bit more.The reason I am looking to do something like this is that having a background in statically typed languages (like C++ and C#) it seems totally natural to me that one should not only want typed scalar references (i.e. pointers) but also typed containers (e.g. lists of T, maps of S -> T and so on). I am just starting out in Cython so it could well be that I've missed something obvious, but judging by this SO question others have also encountered this perplexity and haven't really had their question answered.The problem with a list obviously isn't a big deal, except that once you've stored your typed object in there it's boxed and Cython no longer knows what type it is, so it doesn't optimize member lookups and so on. So, my understanding is, to induce optimized C-level member access you need to unbox it by casting back to your type every time you use it in your code, which seems unnecessarily tedious (as well as having a minor performance impact, if Cython does a dynamic type check - I haven't tried yet).
--
---
You received this message because you are subscribed to the Google Groups "cython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cython-users...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
If you need typed containers you can use C++ standard library containers
from Cython just fine. However, Python classes and Cython extension
classes are not C++ classes and thus have different semantics and cannot
(and should not) be interchangeable.
The fundamental misconception is that Cython is not an alternate syntax
for C++. If you want to code with C++ semantics you are much better
served writing C++ code, rather than abusing Cython.
That said, you can code your Cython typed-list implementation, but I
believe you would have only marginal performance benefits over the
standard python list.
# vector.pyxcdef class A:cdef public int xcdef class Alist:def __init__(self):self.inner = []cdef list innercdef void append(self, A a):self.inner.append(a)cdef A get(self, int i):return <A> self.inner[i]def __len__(self):return len(self.inner)cpdef Alist make_typed_list(int N):cdef A acdef int icdef Alist L = Alist()for i in range(N):a = A()a.x = 1L.append(a)return Lcpdef list make_python_list(int N):cdef A acdef int icdef list L = []for i in range(N):a = A()a.x = 1L.append(a)return Lcpdef long test_python_list(list L) except -1:cdef int icdef long sum = 0for i in range(len(L)):sum += L[i].xreturn sumcpdef long test_typed_list(Alist L) except -1:cdef int icdef long sum = 0for i in range(len(L)):sum += L.get(i).xreturn sum
# test_vector.pyimport pyximportpyximport.install()from vector import *from time import timeL = make_python_list(10000000)start = time()z = test_python_list(L)end = time()print "Python list", end - start, "s"L = make_typed_list(10000000)start = time()z = test_typed_list(L)end = time()print "Typed list", end - start, "s"
It's not too hard to make a reference-counting "smart" pointer (I've
done this several times myself) that would hold a Python reference. It
would require special support from Cython to allow it to be typed for
an extension type. What would we want to call it?
Use a template language of your choice to create the .pyx files. Or do
the (safe or unsafe) cast after accessing the item.
Eventually we'll probably want to support PEP-484 style annotations
for containers, probably with type checking by default and a directive
to disable.
- Robert