[type_traits]Member function traits in function_traits?

It's amazing that function_traits in Boost.type_traits does not support member function traits. As I need this feature recently, I wrote a simple implementation and discuss it with John Maddock, but he gave me following reply: John Maddock <john@johnmaddock.co.uk> wrote:
I don't think this is quite the right approach: function_traits was deliberately written *not* to work with function-pointers - since you can always strip the pointer off before passing the type to function_traits - but handling member function pointers raise some interesting wider questions.
I'm not sure the meaning of "wider questions". Could anyone tell me what is the question and the differences between global function pointers and member function pointers, please? Regards, Realdodo Du realdodo.d@gmail.com

Realdodo Du wrote:
I'm not sure the meaning of "wider questions". Could anyone tell me what is the question and the differences between global function pointers and member function pointers, please?
OK let me try and explain: Function traits only recognises function types, for example given: typedef int ft(int); ft is a function type whose type is "int (int)", you can declare a function with it: ft myproc; // declares int myproc(int) but that's about it. In contrast a function pointer: int (*)(int) or a function reference: int (&)(int) can *not* be passed to function_traits, but you can always use remove_pointer or remove_reference respectively to convert them to something that you can. Now, for member-functions there is no such type as "member function" only pointers to member functions, for example: int (myclass::*)(int) You cannot pass such a type to function_traits, and you can't use remove_pointer to convert it to something that you can either. Now... if you try and extend function_traits to deal with member-function-pointers the you get all kinds of tricky questions, like "what is the functions arity?" - does the hidden "this" pointer count in other words. Then you have to decide what to do about const or volatile qualified functions etc. So... the question might be, why not a remove_member_pointer trait that converts: T (U::*) to T except that no one seems to have thought of let alone needed such a beast until now. So.... the follow up question might be, since your code has to handle member-function-pointers differently from regular function-pointers, why not change: template <class T> void f(T f) { typedef function_traits<typename remove_pointer<T>::type> ft; // use ft here... } to template <class T, class U> void f(T (U::*)) { typedef function_traits<T> ft; // use ft here, T is deduced as a function type } which obviously may or may not look anything like your actual code :-) To conclude, how should this best be handled? John.

Hi John, sorry for jumping into this discussion. It's because ... John Maddock wrote:
So... the question might be, why not a remove_member_pointer trait that converts:
T (U::*) to T
except that no one seems to have thought of let alone needed such a beast until now.
... I certainly have thought of such a beast, but as you probably know, ...
So.... the follow up question might be, since your code has to handle member-function-pointers differently from regular function-pointers, why not change:
template <class T> void f(T f) { typedef function_traits<typename remove_pointer<T>::type> ft; // use ft here... }
to
template <class T, class U> void f(T (U::*)) { typedef function_traits<T> ft; // use ft here, T is deduced as a function type }
... we currently can't really make code like this work reliably, because: - if the member function is cv-qualified the program is ill-formed by the current Standard - if you put U and T back together (e.g. for passing the argument on) the type might be incompatible with the type of the argument (this scenario occurs if cv qualification is silently dropped or when MSVC's thiscall silently becomes cdecl - it happens with the default configuration of this compiler) - some compilers (GCC, maybe others) will find the function template's signature doesn't match a pointer to member function (same problem with template partial specialization)
To conclude, how should this best be handled?
Brute force, I guess ;-). IOW the proposed FunctionTypes lib or something similar. Regards, Tobias

Tobias Schwinger wrote:
... we currently can't really make code like this work reliably, because:
- if the member function is cv-qualified the program is ill-formed by the current Standard - if you put U and T back together (e.g. for passing the argument on) the type might be incompatible with the type of the argument (this scenario occurs if cv qualification is silently dropped or when MSVC's thiscall silently becomes cdecl - it happens with the default configuration of this compiler) - some compilers (GCC, maybe others) will find the function template's signature doesn't match a pointer to member function (same problem with template partial specialization)
Yep, I sort of figured this would open up a whole can of worms :-)
To conclude, how should this best be handled?
Brute force, I guess ;-). IOW the proposed FunctionTypes lib or something similar.
Got it :-) John.
participants (3)
-
John Maddock
-
Realdodo Du
-
Tobias Schwinger