The question is kind of hard to ask without an example so here it is:
#include <vector>
struct O
{
};
struct C
{
template <typename T>
void function1(void (C::*callback)(const O*));
template <typename T>
void function2(void (C::*callback)(const typename T::value_type));
void print(const O*);
};
int main()
{
C c;
c.function1< std::vector<O*> >(&C::print); // Success.
c.function2< std::vector<O*> >(&C::print); // Fail.
}
The error that I am given is:
error: no matching function for call to ‘C::function2(void (C::*)(const O*))’.
Basically, the only difference between calls is that in function2, I’m more generic since I use the typedef std::vector<O*>::value_type which should resolve to O*, hence similar to function1.
I’m using G++ 4.2.1 (I know it’s old), but Comeau confirms I’m wrong.
Why does the compilation fail?
Your problem is that
const typename T::value_typeis basicallytypename T::value_type constwhich resolves toO* constwhich is obviously not the same asconst O*(which would beO const *, when writing the ptr declaration behind the type (more useful to figure out this behaviour)).As for archiving what you want, that entirly depends on what you want. If you want you can use
boost type_traitsortr1 type_traitsto strip the pointer, add const and make it a pointer again like this:Using
tr1instead ofboostshould basically be a matter of replacingboost::withstd::tr1::.However I wouldn’t exactly call this a useful generalization, so you might want to overthink if you really want to go that way. Personally I would either use something like
boost functionor free functions as callbacks, the former allowing for much greater flexibility in what can be used as callbacks (free functions, functors, member functions), while the later at least makes it easy to create a second function which will appropriately convert the arguments (that is if you want to use a function which getsconst O*as parameter, you can create one which takesO*and calls the first one with that parameter and use that one as callback).