如何在cython中将unordered_map从c struct转换为int?
我尝试运行以下代码: Main.py
# !/usr/bin/env python
# encoding: utf-8
import pyximport
pyximport.install()
from foo import Fun
Fun()
Foo.pyx
# cython: experimental_cpp_class_def=True
#!/usr/bin/env python
# encoding: utf-8
from libcpp.unordered_map cimport unordered_map
from libcpp.map cimport map
from libcpp.string cimport string
cdef cppclass mystruct:
int i,j
bint equal_to "operator=="(const mystruct t) const:
return this.i == t.i and this.j == t.j
bint myhash "hash"(const mystruct t) const:
return hash(i)+hash(i) # how to calculate it properly?
def Fun():
cdef:
unordered_map[mystruct,int] dDict
mystruct A
A.i=111
dDict[A]=1234
print A.i
print dDict[A]
foo.pyxbld
def make_ext(modname, pyxfilename):
from distutils.extension import Extension
return Extension(name=modname,
sources=[pyxfilename],
experimental_cpp_class_def=True,
language='C++')
我收到以下错误:
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\INCLUDE\functional(109) : while compiling class template member function 'bool std::equal_to<_Ty>::operator ()(const _Ty &,const _Ty &) const'
with
[
_Ty=__pyx_t_3foo_mystruct
]
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\INCLUDE\xhash(184) : see reference to class template instantiation 'std::equal_to<_Ty>' being compiled
with
[
_Ty=__pyx_t_3foo_mystruct
]
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\INCLUDE\unordered_map(74) : see reference to class template instantiation 'stdext::_Hash_compare<_Kty,_Hasher,_Keyeq>' being compiled
with
[
_Kty=__pyx_t_3foo_mystruct,
_Hasher=std::tr1::hash<__pyx_t_3foo_mystruct>,
_Keyeq=std::equal_to<__pyx_t_3foo_mystruct>
]
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\INCLUDE\xhash(191) : see reference to class template instantiation 'std::tr1::_Umap_traits<_Kty,_Ty,_Tr,_Alloc,_Mfl>' being compiled
with
[
_Kty=__pyx_t_3foo_mystruct,
_Ty=int,
_Tr=stdext::_Hash_compare<__pyx_t_3foo_mystruct,std::tr1::hash<__pyx_t_3foo_mystruct>,std::equal_to<__pyx_t_3foo_mystruct>>,
_Alloc=std::allocator<std::pair<const __pyx_t_3foo_mystruct,int>>,
_Mfl=false
]
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\INCLUDE\unordered_map(86) : see reference to class template instantiation 'stdext::_Hash<_Traits>' being compiled
with
[
_Traits=std::tr1::_Umap_traits<__pyx_t_3foo_mystruct,int,stdext::_Hash_compare<__pyx_t_3foo_mystruct,std::tr1::hash<__pyx_t_3foo_mystruct>,std::equal_to<__pyx_t_3foo_mystruct>>,std::allocator<std::pair<const __pyx_t_3foo_mystruct,int>>,false>
]
C:\Users\LENOVO\.pyxbld\temp.win-amd64-2.7\Release\pyrex\foo.cpp(796) : see reference to class template instantiation 'std::tr1::unordered_map<_Kty,_Ty>' being compiled
with
[
_Kty=__pyx_t_3foo_mystruct,
_Ty=int
]
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\INCLUDE\functional(1265) : error C2440: 'type cast' : cannot convert from 'const __pyx_t_3foo_mystruct' to 'size_t'
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\INCLUDE\functional(1264) : while compiling class template member function 'size_t std::tr1::hash<_Kty>::operator ()(const _Kty &) const'
with
[
_Kty=__pyx_t_3foo_mystruct
]
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\INCLUDE\xhash(183) : see reference to class template instantiation 'std::tr1::hash<_Kty>' being compiled
with
[
_Kty=__pyx_t_3foo_mystruct
]
我应该如何正确定义哈希函数并更正程序以使其工作? 在此先感谢您的帮助。
答案 0 :(得分:1)
问题不在于正确计算哈希值;问题是告诉std C ++ lib使用你定义的那个。为此你要么
必须重载std::hash<mystruct>
但据我所知,这不能通过Cython完成
或者传递额外的模板参数,这会强制您重新包装所有unordered_map
内容,因为Cython只包装了两个参数的默认版本。这还不包括你不得不破解从Cython传递非类型模板参数的事实,因为这还不支持。
所以我的简短回答是:编写一个真正的C ++包装器文件。