Passando um ponteiro para uma função de membro como um argumento de modelo.Por que isso funciona?

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

Pergunta

Tenho um código que 100% funciona para o caso de uso que eu tenho.Eu só estou querendo saber se alguém pode explicar como e por que funciona.

Eu tenho uma classe de modelo que fica entre o código que manipula threading e da comunicação em rede e o usuário da biblioteca para passar os dados recebidos do servidor para o usuário.

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;
};

Este modelo é instanciado e usado na biblioteca de acordo com os tipos de Bar Baz assim:

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 );

Tudo isso funciona e boost::bind chama o getter/setter funções para passar os dados ao redor de onde ele precisa ir. Como e por que o faz passar ponteiros para funções de membro como um argumento de modelo, como neste caso de trabalho?


Em resposta aos comentários, eu não tinha percebido que os ponteiros para funções de membro eram válidos os argumentos de modelo.Não é algo que eu tinha visto "em estado selvagem" antes.Eu tentei e funcionou, mas eu não estava esperando.

Foi útil?

Solução

Eu acho que há uma melhor explicação por que é possível fazê-lo do que "porque a norma diz que":

A razão por que funciona é porque os ponteiros-para-membros são valores constantes conhecido em tempo de compilação (ponteiro-para-membro é efetivamente um deslocamento de um membro, desde o início, de uma classe).Assim, eles podem ser usados como parâmetros de modelos, assim como qualquer outra constante de inteiro pode ser.

Por outro lado, normal ponteiros não são constantes de tempo de compilação, porque eles dependem de layout de memória, que só existe em tempo de execução.Eles não podem ser argumentos de modelo.

Outras dicas

Quando você faz uma pergunta como "por que algo funciona? ", isso implica que o fato de que funciona é de alguma forma surpreendente para você. É impossível responder à pergunta, a menos que você explique Por quê Você acha surpreendente.

Por que funciona? Porque a especificação do idioma diz explicitamente que deve funcionar. Não há outra resposta, até que você explique suas preocupações com mais detalhes.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top