The following program should compile, but current g++ from trunk compiles it.
Please read the comments in the code: ~=~ template<typename T> struct do_typedef { typedef T type; }; template<typename T> struct is_function; // Let's name this template partial specialization #1 template<typename T> struct is_function< T ()> { }; template<typename T> struct is_member_func; template<typename T, typename C> struct is_member_func<T C::*> { //[1] okay, the following line should not compile. Here is why. //After the type substitution that happens at instantiation time, //the value of the argument that matches the T parameter is //'void () () const'. //In that context, the result of the substitution of T in the expression //do_typedef<T>::type _should_ be 'void () () const' as well. //So will be the argument of the is_function template. //'void () () const' is not compatible with 'T ()', so the //partial template specialization #1 should be instantiated. //So we should get a compilation error. is_function<typename do_typedef<T>::type> t; }; struct A; // Should not compile because of the comment [1] above. is_member_func<void (A::*) (void) const> t; ~=~ What happens is that during the type substitution of do_typedef<T>::type, g++ removes the const qualifier from the 'void () () const' function. And that is a bug. I'll attach below a patch that fixes it. -- Summary: G++ remove cv qualifiers from typedefs during template instantiation Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: dodji at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39321