
Hi Paul, allow me to add a few annotations in regard to the library and its documentation. Paul Mensonides wrote:
-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Rob Stewart
Way. We are not talking about the functions, we're talking about their types. In other words, the traits do not inspect individual values of int (*)(int) -- they inspect the type int(*)(int)
itself. I
don't think there's any problem with calling int(*)(int) a
nonmember
function pointer type.
If you're thinking about whether the type is that of a static member function, then you won't be thinking that you should use "nonmember."
Just to be pedantic, the types of member functions are regular function types also.
To be even more pedantic: there are no types of member function types (there are only function types decorated with a pointer to member which as a whole are 'compound non-function types'). But it seems I look at it the very same way: This library provides functionality to classify, decompose and synthesize function types and other compound types directly decorating a function type with a pointer, reference or member pointer. (this is a cite from the very first sentence introducing the library - this revised version of the docs has not been posted yet, however)
Furthermore, you *can* have cv-qualified function types, such as 'int (int) const'.
While theoretically correct, things are too implementation-defined around here to rely on that you can do anything with cv-qualified function types (not decorated with a pointer to member, that is). E.g: typedef int(int) const x; // parse error with GCC We shouldn't use types like this -- this is the reason why the library does not support them.
The differences are that you cannot declare a non-member function with a cv-qualified function type and that the types of pointers to actual functions differ based on whether they are (non-static) member functions. E.g.
typedef void func();
func f;
struct x { func f; };
&f -> void (*)() &x::f -> void (x::*)()
Likewise:
template<class> struct remove_pointer_to_member;
template<class R, class C> struct remove_pointer_to_member { typedef R type; };
remove_pointer_to_member< void (x::*)() >::type -> void ()
Yeah. For the protocol: this code won't work with GCC (doesn't match the specialization) or MSVC ( R is substituted with void __thiscall(x::*)() ). The fact that there can be calling conventions particular to member-functions makes these "add/remove member pointer transformations" even more troublesome.
Basically, the argument between member and non-member doesn't apply to function types. If, OTOH, you're really talking about pointers to functions and pointers to member functions, then a type difference becomes evident and there is a significant distinction. In that case, the types are "pointers to function" (which is the type classification of a pointer to static member function) and "pointer to member function" (which is the type classification of a pointer to non-static member function). I think it is a misuse of terminology to say "the type of a function" and really mean "the type of a pointer to function."
The review version of the library redefined and widened the term "function type" for that matter. I never really liked it and the boostified version will pedantically use the term "function type" as defined by the standard and will not refer to a function pointer as being a function type! Regards, Tobias