/ / ¿Cómo eliminar const de la firma de tipo de plantilla de función miembro? - c ++, templates, visual-c ++, g ++, metaprogramming

¿Cómo eliminar const de la firma de tipo de plantilla de función miembro? - c ++, templates, visual-c ++, g ++, metaprogramming

Estoy trabajando en algunas cosas del sistema de tipo C ++, yEstoy teniendo un problema para eliminar la constancia de una función miembro para usar con las clases de rasgo de función. Lo que realmente es toubling aquí es que esto funciona bien con G ++, pero MSVC10 no puede manejar la especialización parcial correctamente, y no sé Si uno de estos compiladores realmente tiene un error aquí.

La pregunta aquí es, ¿cuál es la forma correcta de eliminar el calificador const de la función miembro de tal manera que pueda obtener una firma de tipo de función?

Tome el siguiente ejemplo de código:

  #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?
}

Las tres declaraciones de PrintType deberían imprimir lo mismo. MSVC10 imprime lo siguiente:

int __cdecl(void)
int __cdecl(void)
int (__cdecl A::*)(void)const __ptr64

g ++ imprime esto (que es el resultado esperado):

FivE
FivE
FivE

Respuestas

3 para la respuesta № 1

Le sugiero que eche un vistazo a TypeTraits.h de la biblioteca loki de Alexandrescu. Proporciona una forma genérica de eliminar calificadores, como const.

http://loki-lib.cvs.sourceforge.net/loki-lib/loki/include/loki/TypeTraits.h?view=markup

Cuando tengo algunos problemas filosóficos con la meta programación c ++ meta programación, tiendo a buscar en el diseño moderno de c ++ si hay una respuesta para mi paradero.


1 para la respuesta № 2

Este ayudaría

template<typename R,typename T> struct RemovePointer<R (T::*)() const> { typedef R Type; };

Tenga en cuenta que probablemente desee agregar () en la línea anterior, también (de lo contrario coincidiría con los punteros a los miembros y los punteros a las funciones):

template<typename R,typename T> struct RemovePointer<R (T::*)()> { typedef R Type; };

1 para la respuesta № 3

typeid(...).name() devuelve una cadena definida por la implementación. Podría ser un símbolo destrozado por el compilador, o un poema escrito por Jon Skeet. Por favor, no confíe en ello para hacer algo útil.

También parece extraño querer quitarle "const"; la función es const, entonces, ¿por qué no quieres eso en la cadena resultante?

No tengo idea de por qué está esperando o viendo "FIvE". No puedo ver nada parecido en su código.