I'm working on some C++ type system stuff, and I'm having a problem removing const-ness from a member function for use with function trait classes. What is really toubling here is that this works fine with G++, but MSVC10 fails to handle the partial specialization correctly, and I do开发者_JS百科n't know if one of these compilers actually has a bug here.
The question here is, what is the correct way to remove the const qualifier from the member function in such a way that I can get a function type signature?
Take the following code sample:
#include <iostream>
template<typename T> struct RemovePointer { typedef T Type; };
template<typename T> struct RemovePointer<T*> { typedef T Type; };
template<typename R,typename T> struct RemovePointer<R (T::*)> { typedef R Type; };
class A {
public:
static int StaticMember() { return 0; }
int Member() { return 0; }
int ConstMember() const { return 0; }
};
template<typename T> void PrintType(T arg) {
std::cout << typeid(typename RemovePointer<T>::Type).name() << std::endl;
}
int main()
{
PrintType(&A::StaticMember);
PrintType(&A::Member);
PrintType(&A::ConstMember); // WTF?
}
All three of these PrintType statements should print the same thing. MSVC10 prints the following:
int __cdecl(void)
int __cdecl(void)
int (__cdecl A::*)(void)const __ptr64
g++ prints this (which is the expected result):
FivE
FivE
FivE
I suggest you take a look at the TypeTraits.h of the loki library by Alexandrescu. It provides a generic way to strip qualifiers, like const.
http://loki-lib.cvs.sourceforge.net/loki-lib/loki/include/loki/TypeTraits.h?view=markup
When I have some philosophical issues with meta programming c++ meta programming I tend to look in Modern c++ design if there is an answer for my whereabouts.
This one would help:
template<typename R,typename T> struct RemovePointer<R (T::*)() const> { typedef R Type; };
Note that you probably want add ()
in previous line, too (otherwise it would match both pointers-to-members and pointers-to-functions):
template<typename R,typename T> struct RemovePointer<R (T::*)()> { typedef R Type; };
typeid(...).name()
returns an implementation-defined string. It could be a compiler-mangled symbol, or a poem written by Jon Skeet. Please don't rely on it to do anything useful.
It also seems odd to want to take "const" off it; the function is const
, so why don't you want that in the resulting string?
I have no idea why you're expecting, or seeing, "FIvE". I can't see anything like it in your code.
精彩评论