下面的代码来自这个文件。它在 Linux 上编译正确,但在 OS X 上编译失败。
我想对自定义间隔的向量进行排序:
stdsort(intervals.begin(), intervals.end(), compare_start_end)
我的比较函数如下:
cdef uint32_t compare_start_end(interval lhs, interval rhs):
if (lhs.start < rhs.start):
return <uint32_t> 1
elif (rhs.start < lhs.start):
return <uint32_t> 0
elif (lhs.end < rhs.end):
return <uint32_t> 1
else:
return <uint32_t> 0
我得到的错误如下:
In file included from epic2/src/read_bam.cpp:651:
/Library/Developer/CommandLineTools/usr/include/c++/v1/algorithm:4117:5: error: no matching function for call to '__sort'
__sort<_Comp_ref>(__first, __last, __comp);
^~~~~~~~~~~~~~~~~
epic2/src/read_bam.cpp:3305:12: note: in instantiation of function template specialization 'std::__1::sort<std::__1::__wrap_iter<__pyx_t_5epic2_3src_8read_bam_interval *>, unsigned int (__pyx_t_5epic2_3src_8read_bam_interval, __pyx_t_5epic2_3src_8read_bam_interval)>'
requested here
std::sort<std::vector<__pyx_t_5epic2_3src_8read_bam_interval> ::iterator,uint32_t (__pyx_t_5epic2_3src_8read_bam_interval, __pyx_t_5epic2_3src_8read_bam_interval)>(__pyx_v_intervals.begin(), __pyx_v_intervals.end(), __pyx_f_5epic2_3src_8read_bam_compare_start_end);
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/algorithm:3914:1: note: candidate function template not viable: no known conversion from 'unsigned int (*)(__pyx_t_5epic2_3src_8read_bam_interval, __pyx_t_5epic2_3src_8read_bam_interval)' to 'unsigned int
(&)(__pyx_t_5epic2_3src_8read_bam_interval, __pyx_t_5epic2_3src_8read_bam_interval)' for 3rd argument; dereference the argument with *
__sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
^
1 warning and 1 error generated.
问题似乎是其中一种类型。
我有
'unsigned int (*)(__pyx_t_5epic2_3src_8read_bam_interval, __pyx_t_5epic2_3src_8read_bam_interval)'
但我的功能期望
unsigned int (&)(__pyx_t_5epic2_3src_8read_bam_interval, __pyx_t_5epic2_3src_8read_bam_interval)
提示是尝试取消引用第三个参数,但这不起作用。
stdsort(intervals.begin(), intervals.end(), dereference(compare_start_end))
相反,它会出错
Compiling epic2/src/read_bam.pyx because it changed.
[1/1] Cythonizing epic2/src/read_bam.pyx
Error compiling Cython file:
------------------------------------------------------------
...
intervals = dereference(it).second
five_ends = intvec()
if drop_duplicates:
stdsort(intervals.begin(), intervals.end(), dereference(compare_start_end))
^
你有什么建议吗?附言。上面在 linux 上编译,但在 macOS 上不编译,所以代码很脆弱。
系统信息
macOS 莫哈韦,10.14.6 (18G87)
gcc --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/c++/4.2.1
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.7.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
最小的可重现示例
# minimal_example.pyx
from libc.stdint cimport uint32_t
from libcpp.algorithm cimport sort as stdsort
from libcpp.vector cimport vector
ctypedef struct interval:
uint32_t start
uint32_t end
ctypedef vector[uint32_t] intvec
ctypedef vector[interval] interval_vector
cdef uint32_t compare_start_end(interval lhs, interval rhs):
if (lhs.start < rhs.start):
return <uint32_t> 1
elif (rhs.start < lhs.start):
return <uint32_t> 0
elif (lhs.end < rhs.end):
return <uint32_t> 1
else:
return <uint32_t> 0
cdef test(interval_vector intervals):
stdsort(intervals.begin(), intervals.end(), compare_start_end)
编译:
folder_with_Python_h="/mnt/work/endrebak/software/anaconda/include/python3.7m/"
cython --cplus minimal_example.pyx
gcc -I $folder_with_Python_h -c minimal_example.cpp -o minimal_example.o -Ofast -Wall -std=c++11
在 macOS 上会弹出相同的错误消息,但不会在 linux 上弹出。
我尝试过的其他命令,给出相同的结果:
g++ -I /Users/endrebakkenstovner/anaconda3/include/python3.6m/ -stdlib=libc++ -c minimal_example.cpp -o minimal_example.o -Ofast -Wall
gcc -I /Users/endrebakkenstovner/anaconda3/include/python3.6m/ -c minimal_example.cpp -o minimal_example.o -Ofast -Wall -lc++
尝试更改 Cython 代码
在 cdef 测试之前添加这些行
cdef extern from "<algorithm>" namespace "std":
void stdsort(...)
结果(在 linux 和 macOS 上)
Error compiling Cython file:
------------------------------------------------------------
...
cdef extern from "<algorithm>" namespace "std":
void stdsort(...)
cdef test(interval_vector intervals):
stdsort(intervals.begin(), intervals.end(), compare_start_end)
^
------------------------------------------------------------
minimal_example.pyx:30:11: ambiguous overloaded method
根据评论结果在 stdsort(...) 末尾添加“排序”(linux和macOS):
Error compiling Cython file:
------------------------------------------------------------
...
else:
return <uint32_t> 0
cdef extern from "<algorithm>" namespace "std":
void stdsort(...) "sort"
^
------------------------------------------------------------