Typedef equivalence in function arguments
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>
v开发者_如何学Gooid 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_type
is basically typename T::value_type const
which resolves to O* const
which is obviously not the same as const O*
(which would be O 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_traits
or tr1 type_traits
to strip the pointer, add const and make it a pointer again like this:
template <typename T>
void function2(void (C::*callback)(typename boost::add_pointer<typename boost::add_const<typename boost::remove_pointer<typename T::value_type>::type>::type>::type));
Using tr1
instead of boost
should basically be a matter of replacing boost::
with std::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 function
or 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 gets const O*
as parameter, you can create one which takes O*
and calls the first one with that parameter and use that one as callback).
精彩评论