【问题标题】:Cython: How to sort vector with closureCython:如何使用闭包对向量进行排序
【发布时间】:2021-12-19 03:39:08
【问题描述】:

我正在使用带有 C++17 标志(高于 C++11 以具有闭包语法)的最新 Cython 到 GCC。 Cython 中的这种 C++ 排序似乎不允许关闭:

# File: myfunc.pyx
from libcpp.vector cimport vector
from libcpp.algorithm cimport sort

# cpdef to call from Python, it just wraps cdef anyway
cpdef myfunc():
    # int is just example, I need to sort struct vector
    cdef vector[int] v 
    v.push_back(2)
    v.push_back(1)

    # Compile error: Expected ')', found 'a'
    sort(v.begin(),v.end(), [](int a,int b){
        return a<b 
    })

Cython 是否支持 C++ 闭包以及如何使用它?如何使用闭包进行 C++ 排序,因为我正在将 Python 移植到 Cython,并且有很多 lambda 排序。

【问题讨论】:

  • 我搜索了超过 1000 页的 C++ 17 标准文档,但我没有看到任何地方提到的 Cython。为什么您期望“cython”会遵守 C++ 标准?
  • 对于自 C++11 以来就存在的 C++ 闭包(毫无疑问,在 C++17 中)
  • 转到the authors 并询问他们。您是否有在 cython 中使用 lambdas 的当前代码?该问题与std::sort 无关,与不支持您的期望有关。 Lambda 可以在没有 STL 的情况下存在。

标签: python c++ lambda migration cython


【解决方案1】:

在这种情况下,您实际上并不需要“闭包”——您不会从周围的范围中捕获任何变量。因此,对于您的特定示例,您可以使用 cdef 函数(必须在全局范围内定义):

cdef bool compare(double a, double b):
    return a<b

sort(v.begin(),v.end(), compare)

这显然不是一个通用的解决方案。但是很多时候传递一个指向 C 函数的指针确实是你所需要的。

【讨论】:

    【解决方案2】:

    我已经尝试搜索和更改代码,但这是唯一的方法:

    • 使用 .hpp 标头
    • 或者使用 Python 的 'sorted' 函数

    使用 .hpp 头文件(如果不使用 C++ 功能,.h 也可以)

    根据我的互联网搜索,Cython 中没有 C++ 闭包语法,请改用带有运算符重载的结构。

    # File: mycmp.hpp
    struct cmp {
        bool operator()(int a,int b){ return a<b; }
    };
    
    # File: myfunc.pyx
    cdef extern from "mycmp.hpp":
        cdef struct cmp:
            bool "operator()"(int a,int b)
    
    cdef vector[int] v
    v.push_back(2)
    v.push_back(1)
    
    cdef cmp compare
    sort(v.begin(),v.end(), compare)
    print(v)
    

    使用 Python 的“排序”函数

    由于.sort 不在vector 上,请改用sorted 函数。这要简单得多,但对于其他类型的 lambda,可能不适用

    v = sorted(v, key=lambda x: x) # x or some prop of x
    

    【讨论】:

    • 请注意,仿函数甚至在 C++ 标准化之前就已经存在,因为它们所做的只是包装调用运算符 operator()。这可能是 Cython 支持这一点的原因——C++ 从第一天起就能够做到这一点。你想要的是在 C++ 正式标准化后新添加的东西,以及后来的修订版(C++ 03 没有 lambdas)。跨度>
    • 是的,.hpp 只是示例
    猜你喜欢
    • 2021-05-26
    • 1970-01-01
    • 2021-12-07
    • 1970-01-01
    • 1970-01-01
    • 2020-01-24
    • 1970-01-01
    • 2021-05-01
    • 2011-02-15
    相关资源
    最近更新 更多