Puntero de variable miembro
-
21-12-2019 - |
Pregunta
Para una estructura dada:
struct foo
{
void fooFunc(){}
int fooVar = 0;
};
Puedo crear un wapper de llamadas a la función: std::mem_fn( &foo::fooFunc )
de modo que pueda pasarlo a otro método y llamarlo a un objeto.
Quiero saber si existe un contenedor de llamadas similar pero para variables miembro.
Por ejemplo, estoy usando un puntero a una variable miembro aquí pero me gustaría usar un contenedor de llamadas:
void bar( std::function< void( foo ) > funcPtr, int foo::* varPtr )
{
foo myFoo;
funcPtr( myFoo );
foo.*varPtr = 13;
}
Solución
NÓTESE BIEN.Nada en su pregunta proviene de STL (que es una biblioteca de la década de 1990), std::function
y std::mem_fn
son parte de la biblioteca estándar de C++, que no es lo mismo.
std::mem_fn
admite funciones miembro y variables miembro, por lo que puede hacer esto para acceder a la variable miembro y configurarla:
foo f;
std::function<int&(foo&)> var( std::mem_fn( &foo::fooVar ) );
var(f) = 1;
Otros consejos
Además de las funciones de los miembros, std::mem_fn
También puede envolver miembros de datos y permitirles acceso de lectura.Entonces lo siguiente funciona:
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 en los comentarios, puede usar el tipo (no especificado) devuelto por mem_fn
sí mismo para establecer el miembro de datos.
foo f;
std::mem_fn(&foo::fooVar)(f) = 13;
O transformarlo en un std::function
usar
void bar( foo& f, std::function<int&(foo&)> fooVarSet )
{
fooVarSet(f) = 26;
}
Si todo lo que estás buscando es una manera de generar un invocable para configurar el fooVar
miembro de datos, y no utilizar std::mem_fn
específicamente para hacer esto, también puedes hacer el trabajo usando una expresión 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;});