Pergunta

Para uma determinada estrutura:

struct foo
{
    void fooFunc(){}
    int fooVar = 0;
};

Posso criar uma chamada wapper para a função: std::mem_fn( &foo::fooFunc ) de modo que eu possa passá-lo para outro método e chamá-lo em um objeto.
Quero saber se existe um wrapper de chamada semelhante, mas para variáveis ​​de membro.

Por exemplo, estou usando um ponteiro para uma variável de membro aqui, mas gostaria de usar um wrapper de chamada:

void bar( std::function< void( foo ) > funcPtr, int foo::* varPtr )
{
    foo myFoo;
    funcPtr( myFoo );
    foo.*varPtr = 13;
}
Foi útil?

Solução

N. B.Nada na sua pergunta é do STL (que é uma biblioteca da década de 1990), std::function e std::mem_fn fazem parte da Biblioteca Padrão C++, o que não é a mesma coisa.

std::mem_fn suporta funções-membro e variáveis-membro, então você pode fazer isso apenas para acessar a variável-membro e defini-la:

foo f;
std::function<int&(foo&)> var( std::mem_fn( &foo::fooVar ) );
var(f) = 1;

Outras dicas

Além das funções de membro, std::mem_fn também pode agrupar membros de dados e permitir acesso de leitura a eles.Então funciona o seguinte:

void print_fooVar(foo& f, std::function<int(foo)> varAccess)
{
    std::cout << varAccess(f) << std::endl;
}

foo f;
print_fooVar(f, std::mem_fn(&foo::fooVar)); // prints 0

Como JonathanWakely menciona nos comentários, você pode usar o tipo (não especificado) retornado por mem_fn para definir o membro de dados.

foo f;
std::mem_fn(&foo::fooVar)(f) = 13;

Ou transformá-lo em um std::function usar

void bar( foo& f, std::function<int&(foo&)> fooVarSet )
{
    fooVarSet(f) = 26;
}

Se tudo o que você está procurando é uma maneira de gerar um callable para definir o fooVar membro de dados e não usando std::mem_fn especificamente para fazer isso, você também pode realizar o trabalho usando uma expressão lambda.

void bar( foo& f, std::function<void(foo)> funcPtr, 
                  std::function<void(foo&, int)> fooVarSet )
{
    funcPtr( f );
    fooVarSet(f, 13);
}

foo f;
bar(f, std::mem_fn(&foo::fooFunc), [](foo& f, int i) {f.fooVar = i;});

Demonstração ao vivo

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