shangjiaxuan
shangjiaxuan

Reputation: 205

Is it possible to have multiple operator& in a class?

I was trying to express a interface where two interfaces composite the same thing, and inherited (single inheritance) by the implementation. The idea is composition over inheritance from the interface class itself. It is something like this:

class A_interface;
class B_interface {
public:
    B_interface(const B_interface& a) = delete;
    B_interface& operator=(const B_interface& a) = delete;
    virtual operator A_interface&() = 0;
protected:
    B_interface() = default;
};

class A_interface {
public:
    A_interface(const A_interface& a) = delete;
    A_interface& operator=(const A_interface& a) = delete;
    virtual operator B_interface&() = 0;
    void afunc()
    {
        printf("Hello from base A\n");
    }
protected:
    A_interface() = default;
};

class B_Impl;
class A_Impl: public A_interface {
public:
    operator B_Impl&();
    virtual operator B_interface&() override;
protected:
    friend B_Impl;
    A_Impl() = default;
};

class B_Impl:public B_interface {
public:
    B_Impl()=default;
    operator A_Impl&();
    virtual operator A_interface&() override;
private:
    A_Impl a;
};


A_Impl::operator B_Impl&()
{
    printf("Hello from A_Impl::operator B_Impl&\n");
    return *(B_Impl*)(((uint8_t*)this)-offsetof(B_Impl, B_Impl::a));
}

A_Impl::operator B_interface&()
{
    printf("Hello from A_Impl::operator B_interface&\n");
    return A_Impl::operator B_Impl&();
}

B_Impl::operator A_Impl&()
{
    printf("Hello from B_Impl::operator A_Impl&\n");
    return a;
}

B_Impl::operator A_interface&()
{
    printf("Hello from B_Impl::operator A_interface&\n");
    return B_Impl::operator A_Impl & ();
}

Now from the outside code:

B_Impl b;
b.operator A_interface &().operator B_interface &().operator A_interface &().afunc();
A_interface& a1 = b;

Output is:

Hello from B_Impl::operator A_interface&
Hello from B_Impl::operator A_Impl&
Hello from A_Impl::operator B_interface&
Hello from A_Impl::operator B_Impl&
Hello from B_Impl::operator A_interface&
Hello from B_Impl::operator A_Impl&
Hello from base A
Hello from B_Impl::operator A_interface&
Hello from B_Impl::operator A_Impl&

Now the question: What do I need to overload to make the following code work?

A_interface* a2 = &b;

Upvotes: 0

Views: 66

Answers (1)

MSalters
MSalters

Reputation: 180020

Literal overloading requires an argument to overload on, but this is the unary operator&. You seem to want to overload on the return type, not the argument.

For that, you need to return a proxy type which has implicit conversions to both A_interface* and B_interface*. These need to be members of the proxy, since you obviously cannot add a constructor to A_interface*. Pointers are built-in types and do not have any member functions, let alone user-defined member types.

Upvotes: 1

Related Questions