开发者

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜