PyObject*
PythonをObject
クラスにラップしようとしています。Python では、すべてがPyObject*
. リストは でありPyObject*
、リスト内の各項目自体がPyObject*
です。これは別のリストになる可能性さえあります。等
fooList[42] = barObj
Proxy パターン ( here ) を使用してスタイル構文を許可しようとしています。
fooList[42]
これで機能するようになったので、拡張してとして使用できるようにしたいと思いObject
ます。具体的には対応できるようになりたい...
fooList[42].myObjMethod()
fooList[42].myObjMember = ...
Object
には多くのメソッドがあり、現在、最初に をインスタンスにfooList[42].myObjMethod()
解決fooList[42]
し、次に を試みます。Proxy
tmpProxy
tmpProxy.myObjMethod()
これは、私がしなければならないことを意味します
void Proxy::myObjMethod(){ return wrapped_ob.myObjMethod(); }
Object
つまり、の各メソッドを を介して手動でリレーしますがProxy
、これは見苦しいものです。
完璧な解決策はありませんが(上記のリンクされた回答を参照)、喜んで使用します:
fooList[42]->myObjMethod()
... 妥協案として、-> をオーバーロードできる(オーバーロードできないのとは対照的に)と見なし.
ます。
ただし、オーバーロードに関するドキュメントが見つかりませんoperator->
。
私の最善の推測は、何らかのオブジェクトへのポインターを返す必要があり (たとえばpObj
)、C++ が を呼び出すことpObj->whatever
です。
以下は私の試みた実装です。ただし、「オブジェクト型の一時オブジェクトのアドレスを取得しています」という警告が表示されます。
私はObject
クラス内に持っています:
const Object operator[] (const Object& key) const {
return Object{ PyObject_GetItem( p, key.p ) };
}
「const 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]
( の 6 番目の要素)Proxy
をラップするインスタンスとして解決されます。と呼びましょう。Object
myList
myItem
今、私は、またはsomeProxy->fooFunc()
それぞれsomeProxy->fooProperty
を呼び出したいです。myItem.fooFunc()
myItem.fooProperty
「オブジェクト型の一時オブジェクトのアドレスを取得しています」という警告が表示されます。