Перегрузка -> оператор для перенаправления членского доступа через прокси
Я пытаюсь завернуть питонаPyObject*
вObject
учебный класс. В Python всеPyObject*
, Список являетсяPyObject*
и каждый элемент в списке сам по себеPyObject*
, Который может быть даже другой список. и т.п.
Я пытаюсь разрешитьfooList[42] = barObj
синтаксис стиля с помощью шаблона Proxy (Вот).
Теперь, когда у меня это работает, я хочу расширить его так, чтобы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' предупреждение.
У меня внутри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
соответственно.
Я сталкиваюсь с'получение адреса временного объекта типа Object' предупреждение.