c++c++11function-pointersautomember-pointers

auto fails to deduce?


struct test 
{
  void f() {};
};
test t1;

using memfun_t = void (test::*)();
memfun_t mf = &test::f;


auto a1 = &test::f; // OK 
auto a2 = t1.*mf;  // error 
auto a3 = &(t1.*mf); // still no luck

Any ideas why this can't be deduced? I would appreciate answers referencing the Standard.

Edit :

I have found a RAD Studio language extension called __closure that appears to be addressing this issue.1 Here is the code :

class base {
public:
    void func(int x) {
    };
};

typedef void(base::*pBaseMember)(int);

class derived : public base {
public:
    void new_func(int i) {
    };
};

int main(int argc, char * argv[]) {
    derived derivedObject;
    void(__closure * derivedClosure)(int);

    // Get a pointer to the ‘new_func’ member.
    // Note the closure is associated with the
    // particular object, ‘derivedObject’.
    derivedClosure = derivedObject.new_func;

    derivedClosure(3); // Call ‘new_func’ through the closure.
    return 0;
}

http://docwiki.embarcadero.com/RADStudio/Seattle/en/Closure


Solution

  • You can't use

    auto a2 = t1.*mf;  // error 
    

    just like you can't use:

    auto a2 = t1.f;
    

    t1.f is not a valid expression. A pointer to a member function cannot be obtained through an instance of the class. Unlike non-member functions, which decay to a function pointer when used like that, member functions don't decay to a member function pointer.

    Relevant text from the C++11 Standard:

    Unary Operators

    ...

    4 A pointer to member is only formed when an explicit & is used and its operand is a qualified-id not enclosed in parentheses. [ Note: that is, the expression &(qualified-id), where the qualified-id is enclosed in parentheses, does not form an expression of type “pointer to member.” Neither does qualified-id, because there is no implicit conversion from a qualified-id for a non-static member function to the type “pointer to member function” as there is from an lvalue of function type to the type “pointer to function” (4.3). Nor is &unqualified-id a pointer to member, even within the scope of the unqualified-id’s class. —end note ]