Pregunta ¿Dónde puedo encontrar una descripción sobre el uso de "int C :: *"?


En un fragmento de código, encuentro algo como:

template<typename T>
class IsClassT {
  private:
    typedef char One;
    template<typename C> static One test(int C::*);
...

La pregunta es ¿dónde puedo encontrar una descripción sobre por qué el uso de "int C :: *" es válido en la definición de Function Test ()?


8
2017-07-31 15:23


origen


Respuestas:


No describiré qué int C::* significa que @Charles Bailey ya lo hizo muy bien. Sin embargo, responderé a tu pregunta:

(...) por qué el uso de "int C :: *" es válido en la prueba de función ()   ¿definición?

El punto clave es que el uso de int C::* (puntero a miembro de tipo int) es válida si y solo si  C es un tipo de clase De lo contrario, el tipo int C::* está mal formado.

Es por eso que tienes

template<typename C> static One test(int C::*);

y muy probablemente en algún lugar debajo

template <typename> static Two test(...);
static const bool value = sizeof(test<T>(0)) == 1;

Cuando test<T>(0) es visto por el compilador, examina los candidatos para test. Encuentra dos:

template<typename C> static One test(int C::*);   
template <typename> static Two test(...);

La primera tiene prioridad sobre la segunda porque 1) ambas son funciones de la plantilla y 2) la elipsis se busca al final. Si el primero está mal formado (es decir. si y solo si  C no es un tipo de clase), entonces es simplemente descartado y la segunda sobrecarga es tomada. Este comportamiento es apodado SFINAE (para la falla de sustitución no es un error).

Probando el tamaño del tipo de devolución (recuerde que sizeof(char) siempre es 1), puede evaluar en tiempo de compilación test se toma, es decir. si T es un tipo de clase o no.


6
2017-07-31 15:54



int C::* es un puntero a un miembro de C de tipo int. Busque "puntero a miembro". La sección del estándar (ISO / IEC 14882: 2003) que trata esta sintaxis de declaración es 8.3.3 Punteros a miembros [dcl.mptr].

Ejemplo de uso

struct Example
{
    int a;
    int b;
};

int test( Example& ex, int Example::* p )
{
    return ex.*p;
}

int main()
{
    Example x = { 3, 5 };
    // Convoluted way of extracting x.a and x.b
    int a = test( x, &Example::a );
    int b = test( x, &Example::b );
}

10
2017-07-31 15:25



Es un puntero al miembro.
Un simple ejemplo para entender Puntero al miembro.

class A
{
   int a;
   int b;
   void DoSomething();
};

int main()
{
   A *ObjPtr;

   //pointer to member a
   int A::*ptr = &A::a;    

   //Usage
   objPtr->*ptr = NULL;

   //pointer to member function
   void (A::*FuncPtr)(void) = &A::DoSomething; 

   //Usage
   (objPtr->*FuncPtr)(void);    

   return 0;
}

2
2017-07-31 15:27