By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,368 Members | 1,544 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,368 IT Pros & Developers. It's quick & easy.

Ambiguous member function pointer

P: n/a
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

Nov 9 '06 #1
Share this Question
Share on Google+
6 Replies


P: n/a
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
Nov 9 '06 #2

P: n/a
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.
Nov 9 '06 #3

P: n/a
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.

Nov 9 '06 #4

P: n/a
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

Nov 9 '06 #5

P: n/a
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*, intfun = 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.
Nov 9 '06 #6

P: n/a
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
Nov 9 '06 #7

This discussion thread is closed

Replies have been disabled for this discussion.