Ambiguous member function pointer

C

Caleb

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
 
V

Victor Bazarov

Caleb said:
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
 
P

Pete Becker

Caleb said:
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.
 
C

Caleb

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.
 
C

Caleb

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
 
P

Pete Becker

Victor said:
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.
 
A

Andrey Tarasevich

Victor said:
...
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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top