问题 模板类中的Cython C ++静态方法


问题

我在C ++中有一个模板类,它有一个静态方法。它看起来或多或少像这样:

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

所以在C ++中你会称之为: Foo<Int>::doSth();。但是在Cython中,调用静态方法的方法是使用classname作为命名空间:

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

但这没有模板的概念。显然,只是传球 Foo<T> 作为命名空间不起作用,因为它转换为 Foo<T>::doStr() 在C ++中,没有具体的类型代替T.

你会怎么用Cython做的?有办法还是解决方法?


12050
2018-06-29 15:35


起源

这不应该像文档中的非静态方法一样解释吗? docs.cython.org/src/userguide/wrapping_CPlusPlus.html#templates - m.s.
不幸的是它没有。写作 cdef extern from "Foo.h" namespace "Foo": shared_ptr[Foo[T]] doSth[T]() 也不起作用。那是因为cython生成C ++代码,如: Foo::doSth<int>();  - Foo丢失后的模板参数。 - piotrMocz


答案:


注意:这个答案在编写时是正确的(并且仍然有效),但您现在应该使用 @Robertwb回答了这个问题 这样做得恰到好处。


我不认为你可以直接在Cython中做到这一点。您可以创建一个普通(非静态方法)c ++模板函数的非常薄的包装器

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

(通过指定用作字符串的实际函数)。这对你没有帮助,因为它不能处理模板。可能是我在你尝试的方式上误导了你...


3
2018-06-29 17:09



包装它对我来说很好,再次感谢你。我只是希望我可以避免修改我的C ++代码,但它仍然非常酷。我会切换到推荐的方式:) - piotrMocz


Cython现在直接支持静态方法;命名空间hack不再是必需或推荐的。

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


6
2017-08-24 07:46