C++ Logo

std-proposals

Advanced search

[std-proposals] Allow conversion of memfunc pointers to func pointers

From: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Date: Fri, 5 Jan 2024 12:40:21 +0000
At least 95% of C++ implementations nowadays use a calling convention
that performs the invocation of a class's member function by moving
all the arguments down one position, and putting the 'this' pointer in
the first position.

So for example on x86_64 on Microsoft Windows, if a normal function
takes three integer arguments, these arguments will be put in RCX,
RDX, R8. If a member function takes three integer arguments, then
RCX,RDX,R8 will be moved down to RDX,R8,R9 and then the 'this' pointer
will be put in RCX.

Only about 4 implementations of C++ leave the function arguments alone
and store the 'this' pointer in another register (for a list of them,
see page 4 of http://www.virjacode.com/papers/paper_nrvo_latest.pdf ).

So anyway, what if we were able to do the following in Standard C++?

    struct Monkey {
        unsigned i;
        virtual unsigned Go(double x) { return i +
static_cast<unsigned>(x + 0.5); }
    };

    int main(void)
    {
        Monkey m = { 8u };

        unsigned (*p)(double) = std::memfunc_to_func( &Monkey::Go, &m );

        std::invoke_func_as_memfunc(p, &m, 45.3);
    }

The function 'memfunc_to_func' would take two arguments:
    (1) A pointer to a member function for class T
    (2) A pointer to an object of type T

It needs the second argument just in case the member function is
virtual and it needs to look at the vtable of the supplied object.

The function 'invoke_fun_as_memfunc' takes two or more arguments:
    (1) A normal function pointer which holds the address of a member function
    (2) An address of an object
    (3) Any arguments to be passed to the member function

Received on 2024-01-05 12:40:31