过载->操作员通过代理转发成员访问 [英] Overload -> operator to forward member-access through Proxy

查看:94
本文介绍了过载->操作员通过代理转发成员访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将Python PyObject*包装在Object类中. 在Python中,所有内容均为PyObject*. 列表是PyObject*,列表中的每个项目本身都是PyObject*. 甚至可能是另一个列表. 等

I'm trying to wrap a Python PyObject* in an Object class. In Python, everything is a PyObject*. A list is a PyObject*, and each item in the list is itself a PyObject*. Which could even be another list. etc.

我正在尝试通过代理模式允许fooList[42] = barObj样式语法(这里).

I'm trying to allow fooList[42] = barObj style syntax by means of a Proxy pattern (here).

现在我可以正常工作了,我想扩展它,以便可以将fooList[42]用作Object.具体来说,我希望能够处理...

Now that I have that working, I want to extend it so that fooList[42] can be used as an Object. Specifically I want to be able to handle...

fooList[42].myObjMethod()
fooList[42].myObjMember = ...

Object有很多方法,目前fooList[42].myObjMethod()首先将fooList[42]解析为Proxy实例(例如tmpProxy),然后尝试tmpProxy.myObjMethod().

Object has a lot of methods, and currently fooList[42].myObjMethod() is going to first resolve fooList[42] into a Proxy instance, say tmpProxy, and then attempt tmpProxy.myObjMethod().

这意味着我必须做

void Proxy::myObjMethod(){ return wrapped_ob.myObjMethod(); }

即很难通过Proxy手动中继Object的每个方法.

i.e. manually relay each of Object's methods through Proxy, which is ugly.

我看不到任何完美的解决方案(请参见上面的链接答案),但我很乐意使用:

I can't see any perfect solution (see the above linked answer), but I would be happy to use:

fooList[42]->myObjMethod()

...作为一种妥协,看到-> (而不是.不能超载).

... as a compromise, seeing as -> can be overloaded (as opposed to . which cannot).

但是,我找不到任何有关operator->重载的文档.

However, I can't find any documentation for overloading operator->.

我最好的猜测是它必须返回一个指向某个对象的指针(例如pObj),而C ++将调用pObj->whatever.

My best guess is that it must return a pointer to some object (say pObj), and C++ will invoke pObj->whatever.

以下是我尝试的实现.但是,我遇到了获取类型为Object的临时对象的地址" 警告.

Below is my attempted implementation. However, I'm running into a 'taking the address of a temporary object of type Object' warning.

在我的Object类中,我有:

const Object operator[] (const Object& key)     const { 
    return Object{ PyObject_GetItem( p, key.p ) }; 
}

请注意,"const Object&" 遇到获取类型为Object的临时对象的地址" .

NOTE that 'const Object&' runs into 'taking the address of a temporary object of type Object' warning.

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 = ...样式语法.

The idea is to allow myList[5]->someMemberObj = ... style syntax.

myList[5]解析为Proxy实例,该实例包装了Object(myList的第六个元素).我们称之为myItem.

myList[5] resolves as a Proxy instance, which is wrapping an Object (the sixth element of myList). Let's call it myItem.

现在,我希望someProxy->fooFunc()someProxy->fooProperty分别调用myItem.fooFunc()myItem.fooProperty.

Now I want someProxy->fooFunc() or someProxy->fooProperty to invoke myItem.fooFunc() or myItem.fooProperty respectively.

我遇到了获取类型为Object的临时对象的地址" 警告.

推荐答案

如果可以更改Object,则可以添加

If you can change Object, you may add

class Object {
public:
    // other code
    const Object* operator -> () const { return this; }
    Object* operator -> () { return this; }
};

还有您的Proxy

Object operator->() { return container[key]; }

例如,

myObj[42]->myFoo = ...

主要等同于

Proxy proxy = myObj[42];
Object obj = proxy.operator ->();
Object* pobj = obj.operator ->(); // so pobj = &obj;
pobj->myFoo = ...

这篇关于过载-&gt;操作员通过代理转发成员访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆