Pasando un puntero a una función miembro como un argumento de plantilla. ¿Por qué funciona esto?

StackOverflow https://stackoverflow.com/questions/1882740

Pregunta

Tengo un código que funciona al 100% para el caso de uso lo que tengo. Me pregunto si alguien puede explicar cómo y por qué funciona.

Tengo una clase de plantilla que se encuentra entre un cierto código que se encarga de roscado y la comunicación en red y el usuario de la biblioteca para pasar los datos recibidos desde el servidor al usuario.

template <class Bar,
          class Baz,
          class BazReturnType,
          void (Bar::*BarSetterFunction)(const BazReturnType &),
          BazReturnType (Baz::*BazGetterFunction)(void) const>
class Foo
{
    Foo( Bar *bar )
        : m_bar(bar)
    {
    }

    void FooMemberFunction( const Baz *baz )
    {
        boost::bind( BarSetterFunction, m_bar,
                     boost::bind( BazGetterFunction, baz )() ) ();
    }

    Bar *m_bar;
};

Esta plantilla se crea una instancia y se utiliza en la biblioteca en función de los tipos de barra y Baz, así:

typedef Foo<MyBar,
            MyBaz,
            ReturnTypeFromBazGetterFunction,
            &MyBar::ActualSetterFunction,
            &MyBaz::ActualGetterFunction >
    MyFoo;

MyBar *bar = new MyBar;
MyBaz *baz = new MyBaz;
MyFoo *f = new MyFoo( bar );
f->FooMemberFunction( baz );

Todo esto funciona y boost :: bind llama a las funciones de captador / definidor para pasar los datos en torno a donde tiene que ir. ¿Cómo y por qué pasar punteros a funciones miembro como un argumento de plantilla como en este caso el trabajo?


En respuesta a los comentarios, no se había dado cuenta de que los punteros a funciones miembro son válidos argumentos de plantilla. No es algo que había visto "en estado salvaje" antes. Lo probé y funcionó, pero no esperaba que.

¿Fue útil?

Solución

Creo que hay una mejor explicación de por qué es posible hacerlo que "debido a que la norma dice así":

La razón por la que funciona es porque los punteros a miembros son valores constantes conocidos en tiempo de compilación (puntero a miembro está efectivamente un desplazamiento de un miembro desde el inicio de una clase). Por lo tanto se pueden utilizar como parámetros de plantillas, así como cualquier otra constante entera puede ser.

Por otro lado, los punteros son normales no compilan constantes de tiempo, ya que dependen de la capa de memoria que sólo existe en tiempo de ejecución. No pueden ser argumentos de plantilla.

Otros consejos

Cuando usted hace una pregunta en la línea de "¿por algo obras?", Que implica que el hecho de que funciona es en cierto modo sorprendente para usted. Es imposible responder a la pregunta a menos que explique por ¿Por qué Le resulta sorprendente.

¿Por qué funciona? Debido a que la especificación del lenguaje dice explícitamente que deberá trabajar. No hay otra respuesta, hasta que explique sus preocupaciones con más detalle.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top