As discussed in the comments, the issue you’re having is because Cython doesn’t really support non-type template arguments. A workround (hacky and probably fragile) is to trick Cython into thinking it’s providing a type template argument:
cdef extern from "<array>" namespace "std" nogil :
cdef cppclass two "2":
pass
cdef cppclass array[T, U]:
T& operator[](size_t)
# this is obviously very very cut down
def f():
cdef array[int,two] x
return x[0]+x[1]
The trick is that if you do cdef cppclass name "somestring"
Cython will just blindly replace somestring
for name, which generates the correct C++ code. There are obviously some limitations with this approach but for simple usage it should be fine.