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.