Ambiguous member function pointer

Discussion in 'C++' started by Caleb, Nov 9, 2006.

  1. Caleb

    Caleb Guest

    I have a class that has two member functions of the same name:

    class MyClass {
    public:
    void someFunction(int arg);
    void someFunction(int arg, char blah);
    };

    I'm trying to get a tr1::functional to the first one, for example:

    std::tr1::function<void (MyClass*, int)> func_obj;
    func_obj = &Myclass::someFunction;

    But compilation fails on the second line, since MyClass::someFunction
    is ambiguous.

    The only way around it I've found is to first create a member function
    pointer, then pass that to the constructor of the function object.

    I'm curious if there's a better way to do it, or if I'm stuck with
    using function pointers as intermediates? I'm using linux gcc 4.1.

    Thanks,
    Caleb
    Caleb, Nov 9, 2006
    #1
    1. Advertising

  2. Caleb wrote:
    > I have a class that has two member functions of the same name:
    >
    > class MyClass {
    > public:
    > void someFunction(int arg);
    > void someFunction(int arg, char blah);
    > };
    >
    > I'm trying to get a tr1::functional to the first one, for example:
    >
    > std::tr1::function<void (MyClass*, int)> func_obj;
    > func_obj = &Myclass::someFunction;
    >
    > But compilation fails on the second line, since MyClass::someFunction
    > is ambiguous.
    >
    > The only way around it I've found is to first create a member function
    > pointer, then pass that to the constructor of the function object.
    >
    > I'm curious if there's a better way to do it, or if I'm stuck with
    > using function pointers as intermediates? I'm using linux gcc 4.1.


    I am not very proficient with TR1 yet, so educate me, if you will.
    Does the use of 'std::tr1::function' suddenly allow conversion between
    a pointer-to-member and a pointer-to-function (disallowed by the C++
    language proper definition)?

    void (MyClass::*)(int)

    and

    void (*)(MyClass*, int)

    are not the same type. Does 'std::tr1::function' somehow overcome
    the problem of those types' incompatibility?

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Nov 9, 2006
    #2
    1. Advertising

  3. Caleb

    Pete Becker Guest

    Caleb wrote:
    > I have a class that has two member functions of the same name:
    >
    > class MyClass {
    > public:
    > void someFunction(int arg);
    > void someFunction(int arg, char blah);
    > };
    >
    > I'm trying to get a tr1::functional to the first one, for example:
    >
    > std::tr1::function<void (MyClass*, int)> func_obj;
    > func_obj = &Myclass::someFunction;


    typedef void (MyClass::*fptr)(int);

    func_obj = (fptr)&MyClass::someFunction;

    You can also do it without the typedef, but it's a bit more confusing.

    --

    -- Pete
    Roundhouse Consulting, Ltd. -- www.versatilecoding.com
    Author of "The Standard C++ Library Extensions: a Tutorial and
    Reference." For more information about this book, see
    www.petebecker.com/tr1book.
    Pete Becker, Nov 9, 2006
    #3
  4. Caleb

    Caleb Guest

    > I am not very proficient with TR1 yet, so educate me, if you will.
    > Does the use of 'std::tr1::function' suddenly allow conversion between
    > a pointer-to-member and a pointer-to-function (disallowed by the C++
    > language proper definition)?


    It allows it in the sense that you can do this:

    class MyClass {
    void someFunction(int)
    };

    std::tr1::function<int (MyClass*, int)> func;
    func = &MyClass::someFunction;

    MyClass mc;
    func(&mc, 10);

    I assume there's some magic going on behind the scenes. But my issue
    is that if MyClass::someFunction is ambiguous, it won't compile. I'm
    looking for a way to tell the compiler which someFunction to use.
    Caleb, Nov 9, 2006
    #4
  5. Caleb

    Caleb Guest

    > typedef void (MyClass::*fptr)(int);
    >
    > func_obj = (fptr)&MyClass::someFunction;
    >
    > You can also do it without the typedef, but it's a bit more confusing.


    Thanks, Pete. This is what I was looking for.

    Caleb
    Caleb, Nov 9, 2006
    #5
  6. Caleb

    Pete Becker Guest

    Victor Bazarov wrote:
    >
    > I am not very proficient with TR1 yet, so educate me, if you will.
    > Does the use of 'std::tr1::function' suddenly allow conversion between
    > a pointer-to-member and a pointer-to-function (disallowed by the C++
    > language proper definition)?
    >
    > void (MyClass::*)(int)
    >
    > and
    >
    > void (*)(MyClass*, int)
    >
    > are not the same type. Does 'std::tr1::function' somehow overcome
    > the problem of those types' incompatibility?
    >


    Yup, as do std::tr1::mem_fn, std::tr1::bind, and
    std::tr1::reference_wrapper. You can wrap a pointer to member function
    inside any of them, and you get a callable object whose function call
    operator takes an argument that's a pointer or reference to an object,
    and calls the member function on that object. In particular,
    std::tr1::function<void(MyClass*, int)> defines a type with a function
    call operator that takes two arguments, the first of type MyClass* and
    the second of type int, and returns void.

    struct S // sorry, MyClass is too long to type.
    {
    void f(int);
    };

    void g(S*, int);

    S *sp = new S;
    std::tr1::function<S*, int> fun = g;
    fun(s, 3); // calls g(s, 3)
    s = &S::f; // yes, this assignment is intentional
    fun(s, 3); // calls (s->*f)(3);

    There's actually quite a bit more you can do, like wrap a pointer to
    member data (creating a type with a function call operator that takes
    exactly one argument), and you can call member functions with objects,
    references to objects, pointers to objects, and smart pointers to
    objects. For a more complete description, see sections 6.1 and 6.2 of my
    book, "The C++ Standard Library Extensions."

    --

    -- Pete
    Roundhouse Consulting, Ltd. -- www.versatilecoding.com
    Author of "The Standard C++ Library Extensions: a Tutorial and
    Reference." For more information about this book, see
    www.petebecker.com/tr1book.
    Pete Becker, Nov 9, 2006
    #6
  7. Victor Bazarov wrote:
    > ...
    > Does the use of 'std::tr1::function' suddenly allow conversion between
    > a pointer-to-member and a pointer-to-function (disallowed by the C++
    > language proper definition)?
    >
    > void (MyClass::*)(int)
    >
    > and
    >
    > void (*)(MyClass*, int)
    >
    > are not the same type. Does 'std::tr1::function' somehow overcome
    > the problem of those types' incompatibility?
    > ...


    Take a look at

    http://www.ddj.com/184406110

    and, in particular, listing four

    http://www.ddj.com/184406110#l4

    Note, that it doesn't deal with the ever-so-popular problem of converting 'void
    (MyClass::*)(int)' to 'void (*)(int)', i.e. it does not implement the so called
    "closure" functionality. It simply converts the implicit 'this' parameter into
    and explicit one. The latter is not that difficult to achieve with a simple wrapper.

    --
    Best regards,
    Andrey Tarasevich
    Andrey Tarasevich, Nov 9, 2006
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Newsgroup - Ann
    Replies:
    5
    Views:
    603
    John Carson
    Jul 30, 2003
  2. slide_o_mix
    Replies:
    0
    Views:
    420
    slide_o_mix
    Oct 15, 2003
  3. Alex
    Replies:
    0
    Views:
    392
  4. Fraser Ross
    Replies:
    4
    Views:
    1,041
    Fraser Ross
    Aug 14, 2004
  5. somenath
    Replies:
    2
    Views:
    155
    somenath
    Aug 29, 2013
Loading...

Share This Page