Статические методы Cython С++ в классе шаблонов

Проблема

У меня есть шаблонный класс в С++, который имеет статический метод. Это выглядит примерно так:

template<typename T>
class Foo {
    static std::shared_ptr<Foo<T>> doSth();
}

поэтому в С++ вы бы назвали его следующим: Foo<Int>::doSth();. Однако в Cython способ вызова статических методов заключается в использовании имени класса как пространства имен:

cdef extern from "Bar.h" namespace "Bar":
    shared_ptr[Bar] doSth()  # assuming shared_ptr is already declared

но это не имеет понятия шаблонов. Очевидно, что просто передача Foo<T> в качестве пространства имен не работает, потому что она переводится в Foo<T>::doStr() в С++, для T не заменяется конкретный тип.

Вопрос

Как бы вы это делали в Китоне? Есть ли способ или обходной путь?

Ответ 1

Примечание. Этот ответ был прав в то время, когда он был написан (и все еще работает), но теперь вы должны использовать @Robertwb ответ на этот вопрос, чтобы сделать это правильно.


Я не думаю, что вы можете сделать это прямо в Китоне. Вы можете создать очень тонкую оболочку нормальной (нестатической) функции шаблона С++

template <typename T>
std::shared_ptr<Foo<T>> Foo_T_doSth<T>() {
   return Foo<T>::doSth();
}

а затем оберните этот метод в Cython

cdef extern from "..."
    shared_ptr[T] Foo_T_doSth[T]()

Как и в стороне, рекомендуемый способ обертывания статических методов в Cython выглядит (от https://groups.google.com/forum/#!topic/cython-users/xaErUq2yY0s)

cdef extern from "...":
   cdef Foo_doSth "Foo::doSth"()  # not declared as a memeber

(путем указания фактической функции для использования в качестве строки). Это не поможет вам, потому что оно не справляется с шаблонами. Возможно, это я неправильно информировал вас о том, как вы пытались...

Ответ 2

Статические методы теперь непосредственно поддерживаются Cython; перехват пространства имен больше не нужен или не рекомендуется.

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