我正在尝试将 Python 包装PyObject*
在一个Object
类中。在 Python 中,一切都是PyObject*
. 列表是 a PyObject*
,列表中的每个项目本身都是 a PyObject*
。这甚至可能是另一个列表。等等
我正在尝试fooList[42] = barObj
通过代理模式(此处)来允许样式语法。
现在我已经开始工作了,我想扩展它,以便fooList[42]
可以用作Object
. 具体来说,我希望能够处理......
fooList[42].myObjMethod()
fooList[42].myObjMember = ...
Object
有很多方法,目前fooList[42].myObjMethod()
打算先解析fooList[42]
成一个Proxy
实例,say tmpProxy
,然后再尝试tmpProxy.myObjMethod()
。
这意味着我必须做
void Proxy::myObjMethod(){ return wrapped_ob.myObjMethod(); }
即通过 手动中继每个Object
方法Proxy
,这很丑陋。
我看不到任何完美的解决方案(请参阅上面的链接答案),但我很乐意使用:
fooList[42]->myObjMethod()
...作为一种折衷方案,看到 as ->可以重载(而不是不能重载.
)。
但是,我找不到任何有关重载的文档operator->
。
我最好的猜测是它必须返回一个指向某个对象(比如pObj
)的指针,而 C++ 将调用pObj->whatever
.
下面是我尝试的实现。但是,我遇到了“获取 Object 类型的临时对象的地址”警告。
在我的Object
班级里,我有:
const Object operator[] (const Object& key) const {
return Object{ PyObject_GetItem( p, key.p ) };
}
请注意,“const Object&”会遇到“获取 Object 类型的临时对象的地址”警告。
class Proxy {
private:
const Object& container;
const Object& key;
public:
// at this moment we don't know whether it is 'c[k] = x' or 'x = c[k]'
Proxy( const Object& c, const Object& k ) : container{c}, key{k}
{ }
// Rvalue
// e.g. cout << myList[5] hits 'const Object operator[]'
operator Object() const {
return container[key];
}
// Lvalue
// e.g. (something = ) myList[5] = foo
const Proxy& operator= (const Object& rhs_ob) {
PyObject_SetItem( container.p, key.p, rhs_ob.p );
return *this; // allow daisy-chaining a = b = c etc, that's why we return const Object&
}
const Object* operator->() const { return &container[key]; }
// ^ ERROR: taking the address of a temporary object of type Object
};
这个想法是允许myList[5]->someMemberObj = ...
样式语法。
myList[5]
解析为一个Proxy
实例,它包装了一个Object
(的第六个元素myList
)。让我们称之为myItem
。
现在我想someProxy->fooFunc()
或分别someProxy->fooProperty
调用myItem.fooFunc()
或myItem.fooProperty
。
我遇到了“获取对象类型的临时对象的地址”警告。