Peter Dimov wrote: (Hi, Peter. I'm merging two different posts on this subject and replying to both simultaneously.)
>>> Yes, exactly. Apologies for the confusion. It is a common mistake to >>> provide only R T::* and expect that to match all pointers to >>> members. To get back to your earlier post, >>> >>> int (X::*pf) () const; >>> >>> is not the same as >>> >>> typedef int (*F) () const; > > Should be typedef int F() const; > >>> since the first typedef is ill-formed, function types cannot be >>> cv-qualified. > > That's 9.3/9, and yes, you are right, the typedef is legal. Yes an no. The typedef is ill-formed, but not directly because of the cv-qualification. To be technically accurate here, you cannot form a regular pointer (or reference) to a cv-qualified function type. It is prohibited. I.e. typedef int F() const; // legal typedef int (*F)() const; // illegal typedef int (&F)() const; // illegal > I learn > something new every day. Even though 3.9.3/1 implies that functions > cannot > be cv-qualified, and 8.3.5/4 says that creating a cv-qualified > function type makes the program ill-formed, R T::* still matches a > const member function, creating a const qualified function type as R. > Or so Comeau says. C++ sure moves in mysterious ways. Comeau is correct here. I'll spend a few words to clarify the subject though. Normal cv-qualification is compounded from some other type, as in "const T." In the case of function types however, cv-qualification is not compounded. It is inherently part of the base function type or it isn't. So, from a certain point-of-view, the above is accurate. You cannot take a function type and cv-qualify it. However, the function type itself might already be cv-qualified. In other words, cv-qualification on functions is not normal cv-qualification. Specifically, it refers to the cv-qualification of the implicit this pointer. E.g. something like this pseudo code: typedef void f() const; ...roughly equivalent (in pseudocode) to this: typedef void f(const class* this); ...which is why certain limitations exist on cv-qualified function types. Specifically, they can only be used in three ways: 1) to declare a non-static member function 2) to declare the pointed-to type of a pointer-to-member, and 3) to declare another typedef. Note that in the first two cases (i.e. the cases of actual use), the pseudo-type 'class' in the above can be deduced, either from the enclosing class or from the pointer-to-member class type. Any other use is illegal--such as forming a regular pointer or reference to a cv-qualified function type. Then second case is interesting in the particular case of detecting pointers-to-member-functions. The following is all legal: typedef void F() const; struct X { F f; }; void X::f() const { } F X::* pf = &X::f; By the same token, the function type 'F' can be extracted from a pointer-to-member-function with the specialization "R X::*" with 'R' being the original function type: #include <iostream> template<class, class> struct is_same { enum { value = false }; }; template<class T> struct is_same<T, T> { enum { value = true }; }; template<class> struct extract; template<class R, class C> struct extract<R C::*> { enum { value = is_same<R, F>::value }; }; int main() { std::cout << extract<F X::*>::value // 1 << &std::endl; return 0; } Just for the record, however, Comeau doesn't get this whole area right (and many other compilers don't get it right at all). Comeau doesn't consider the type extracted from a pointer-to-member-function to be a regular function type. Rather, it considers it to be some type of psuedo-function-type ala "member function type"--which is incorrect. An example demonstrates this: #include <iostream> #include <typeinfo> typedef void F(); struct X { }; typedef F X::* PMF; template<class> struct extract; template<class R, class C> struct extract<R C::*> { typedef R type; }; extract<PMF>::type f; // decl: no error void f() { return; } // def: error int main() { std::cout << typeid(f).name() // compiler crash // i.e. not an ICE << &std::endl; return 0; } I've been talking about this issue with Daveed Vandevoorde for the last couple weeks, so EDG is aware of the issue. Paul Mensonides _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost