首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >vector_indexing_suite返回的奇怪对象

vector_indexing_suite返回的奇怪对象
EN

Stack Overflow用户
提问于 2015-09-14 14:47:59
回答 1查看 573关注 0票数 0

我有一个

代码语言:javascript
复制
std::vector<const T*>

从c++函数返回:

代码语言:javascript
复制
getallTs()

我把T级课程暴露在:

代码语言:javascript
复制
class_<T,T*> 

向量是这样的:

代码语言:javascript
复制
class_<std::vector<const T*> >("TsList")
  .def(vector_indexing_suite<std::vector<const T*>,true>())
;

NoProxy的论点是什么意思?

我将函数公开如下:

代码语言:javascript
复制
  def("getallTs", getallTs,
      return_value_policy<return_by_value>{});

我观察到一种奇怪的行为。

当我从python打来的时候

代码语言:javascript
复制
tlist = getallTs()

我得到一个TsList对象。

代码语言:javascript
复制
len(tlist)

很管用。

代码语言:javascript
复制
tlist[<anycorrectindex>].<someattribute> 

也很管用。

不过,如果我只是

代码语言:javascript
复制
print(tlist[0])

代码语言:javascript
复制
print(tlist[100])

python打印

代码语言:javascript
复制
object T at <address>

这个地址对于tlist中的所有Ts都是相同的。

而且,我不能使用pythonfor循环迭代Tlist。

代码语言:javascript
复制
for t in tlist: 

不起作用。

有什么想法吗?我向python公开向量和函数的方式有什么问题?

我理解每个包一个c++ T的python对象,持有一个指向T的原始指针。这些T实例存在于全局表的整个过程中。

c++函数重新运行指向这些实例的指针向量。indexing_suite对这些做了什么?

谢谢,

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-09-17 14:45:16

当按索引访问元素时,索引套件默认为元素提供代理,作为为Python用户通常期望的可更改类型提供引用语义的一种方法:

代码语言:javascript
复制
val = c[i]
c[i].m()            # Mutates state, equivalent to `val.m()`
assert(val == c[i]) # Have same state.
val.m()
assert(val == c[i]) # Have same state.

在上面的示例中,val是一个代理对象,它知道容器元素。当NoProxytrue时,在索引时获得值语义,从而在每次索引访问上产生一个副本。

代码语言:javascript
复制
val = c[i]  # val is a copy.
c[i].m()    # Modify a copy of c[i].
assert(val == c[i]) # These have the same state because c[i] returns a new copy.
val.m()
assert(val != c[i]) # These do not have the same state.

当不使用代理时,只有在对元素的引用(例如在迭代期间)上调用时,元素的突变才会持续:

代码语言:javascript
复制
for val in c:
    val.m() # modification observed in c[#]

调用print(c[i])时,将创建一个临时代理对象并将其传递给print,代理对象的生存期将在从print()返回时结束。因此,可以重用临时代理对象使用的内存和标识。这可能导致一些元素似乎具有相同的标识:

代码语言:javascript
复制
id0 = id(c[0]) # id of the temporary proxy
id1 = id(c[1]) # id of another temporary proxy
assert(id0 ?? id1) # Non-deterministic if these will be the same.
assert(c[0] is not c[1]) # Guaranteed to not be the same.

另一方面,在代理的生存期内,同一元素的其他代理将具有相同的标识,而不同元素的代理将具有不同的标识:

代码语言:javascript
复制
c0 = c[0]   # proxy to element 0.
c0_2 = c[0] # another proxy to element 0.
c1 = c[1]   # proxy to element 1
assert(c0 is c0_2)
assert(c0 is c[0])
assert(c0 is not c1)

TT*公开为持有的情况下,如果没有将const T*转换为Python对象,则std::vector<const T*>上的迭代将失败。将类T公开为T*持有,将自动注册为-Python,而非const T*的-Python转换。在Python中迭代集合时,返回对元素的引用,导致无法从const T*构造Python对象。另一方面,当通过索引访问元素时,生成的Python对象要么是代理,要么是副本,可以使用现有的转换器。要解决这一问题,可以考虑:

  • std::vector<>的元素类型与T的持有类型相同。
  • 显式注册const T*到-Python转换器
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32567771

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档