Sobrecarga -> operador para encaminhar o acesso do membro através do Proxy
Estou tentando embrulhar um PythonPyObject*
em umObject
classe. No Python, tudo é umPyObject*
. Uma lista é umaPyObject*
, e cada item da lista é ele próprio umPyObject*
. O que poderia até ser outra lista. etc.
Estou tentando permitirfooList[42] = barObj
sintaxe de estilo por meio de um padrão Proxy (aqui)
Agora que tenho esse trabalho, quero estendê-lo para quefooList[42]
pode ser usado comoObject
. Especificamente, eu quero ser capaz de lidar com ...
fooList[42].myObjMethod()
fooList[42].myObjMember = ...
Object
tem muitos métodos e atualmentefooList[42].myObjMethod()
vai resolver primeirofooList[42]
dentro deProxy
exemplo, digamostmpProxy
e tentetmpProxy.myObjMethod()
.
Isso significa que eu teria que fazer
void Proxy::myObjMethod(){ return wrapped_ob.myObjMethod(); }
ou seja, retransmitir manualmente cada um dosObject
métodos atravésProxy
, que é feio.
Não consigo encontrar nenhuma solução perfeita (veja a resposta vinculada acima), mas ficaria feliz em usar:
fooList[42]->myObjMethod()
... como um compromisso, visto que ->pode sobrecarregado (ao contrário de.
que não pode).
No entanto, não consigo encontrar nenhuma documentação para sobrecargaoperator->
.
Meu melhor palpite é que ele deve retornar um ponteiro para algum objeto (digamospObj
) e o C ++ chamarápObj->whatever
.
Abaixo está minha tentativa de implementação. No entanto, estou encontrando um'pegando o endereço de um objeto temporário do tipo Object' Aviso.
Eu tenho dentro da minhaObject
classe:
const Object operator[] (const Object& key) const {
return Object{ PyObject_GetItem( p, key.p ) };
}
NOTE que 'const Object' é executado em'pegando o endereço de um objeto temporário do tipo Object' Aviso.
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
};
A ideia é permitirmyList[5]->someMemberObj = ...
sintaxe de estilo.
myList[5]
resolve como umProxy
instância, que está envolvendo umObject
(o sexto elemento demyList
) Vamos chamá-lomyItem
.
Agora eu querosomeProxy->fooFunc()
ousomeProxy->fooProperty
invocarmyItem.fooFunc()
oumyItem.fooProperty
respectivamente.
Estou encontrando um'pegando o endereço de um objeto temporário do tipo Object' Aviso.