I have a template class in C++ that has a static method. It looks more or less like this:
template<typename T>
class Foo {
static std::shared_ptr<Foo<T>> doSth();
}
so in C++ you would call it like: Foo<Int>::doSth();
. In Cython however, the way to call static methods is by using the classname as a namespace:
cdef extern from "Bar.h" namespace "Bar":
shared_ptr[Bar] doSth() # assuming shared_ptr is already declared
but this has no notion of templates. Obviously, simply passing Foo<T>
as a namespace doesn't work, because it translates to Foo<T>::doStr()
in C++, no concrete type is substituted for T.
How would you do that in Cython? Is there a way, or a workaround?
Templates and Static variables in C++. Function templates and static variables: Each instantiation of function template has its own copy of local static variables. For example, in the following program there are two instances: void fun(int ) and void fun(double ). So two copies of static variable i exist.
However, for performance critical code, it is often helpful to add static type declarations, as they will allow Cython to step out of the dynamic nature of the Python code and generate simpler and faster C code - sometimes faster by orders of magnitude.
Class templates and static variables: Each instantiation of class template has its own copy of member static variables. For example, in the following program there are two instances Test and Test. So two copies of static variable count exist.
To make use of C data types in Python syntax, you need to import the special cython module in the Python module that you want to compile, e.g. Cython is a Python compiler. This means that it can compile normal Python code without changes (with a few obvious exceptions of some as-yet unsupported language features, see Cython limitations ).
Static methods are now directly supported by Cython; the namespace hack is no longer necessary or recommended.
cdef extern from "Foo.h":
cdef cppclass Foo[T]:
@staticmethod
shared_ptr[Foo[T]] doSth() # assuming shared_ptr is already declared
cdef shared_ptr[Foo[int]] shared_ptr_value = Foo[int].doSth()
http://docs.cython.org/en/latest/src/userguide/wrapping_CPlusPlus.html#static-member-method
Note: This answer was right at the time it was written (and does still work) but you should now use @Robertwb's answer to this question instead to do this properly.
I don't think you can do it directly in Cython. You could create very thin wrapper of a normal (non-static-method) c++ template function
template <typename T>
std::shared_ptr<Foo<T>> Foo_T_doSth<T>() {
return Foo<T>::doSth();
}
and then wrap this method in Cython
cdef extern from "..."
shared_ptr[T] Foo_T_doSth[T]()
As an aside, the recommended way of wrapping static methods in Cython looks to be (from https://groups.google.com/forum/#!topic/cython-users/xaErUq2yY0s)
cdef extern from "...":
cdef Foo_doSth "Foo::doSth"() # not declared as a memeber
(by specifying the actual function to use as a string). This doesn't help you here because it doesn't cope with templates. It may have been me who mis-advised you on the way you were trying...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With