problemas mem_fun_ref
-
09-09-2019 - |
Pregunta
Estoy teniendo problemas para averiguar mem_fun_ref
. Tengo que admitir, que suelen utilizar palabras funcionales para este tipo de cosas, ya que pueden ser inline para la velocidad y la ganancia. Sin embargo, este código no va a ser un cuello de botella y así que quería probar esta cosa.
Este es un ejemplo de lo que quiero hacer. Sé que hay otras maneras de hacerlo. No quiero utilizar copy
, no quiero utilizar funciones miembro gama, no quiero usar un back_inserter
. Específicamente quiero usar mem_fun_ref
. Esto es sólo un ejemplo sencillo, el caso real es mucho más complicado. Dicho esto, yo realmente no sé por qué esto está mal, pero no estoy familiarizado con mem_fun_ref
o mem_fun
.
Esto es lo que quiero trabajar:
#include <list>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
int main()
{
list<int> a;
a.push_back(1);
a.push_back(2);
a.push_back(3);
vector<int> b;
// should work like magic!
for_each(a.begin(), a.end(), bind1st(mem_fun_ref(&vector<int>::push_back), b));
}
Pero consigo 3 errores:
1>c:\program files\microsoft visual studio 9.0\vc\include\functional(276) : error C2529: '_Right' : reference to reference is illegal
1>c:\program files\microsoft visual studio 9.0\vc\include\functional(281) : error C2529: '_Right' : reference to reference is illegal
1>c:\program files\microsoft visual studio 9.0\vc\include\functional(282) : error C2535: 'void std::binder1st<_Fn2>::operator ()(const int &(&)) const' : member function already defined or declared
1> with
1> [
1> _Fn2=std::mem_fun1_ref_t<void,std::vector<int>,const int &>
1> ]
1> c:\program files\microsoft visual studio 9.0\vc\include\functional(276) : see declaration of 'std::binder1st<_Fn2>::operator ()'
1> with
1> [
1> _Fn2=std::mem_fun1_ref_t<void,std::vector<int>,const int &>
1> ]
reference to reference is illegal
me hace pensar que la función necesita tener un parámetro por valor. Pero, por supuesto, esto no es posible cambiar en vector
, y no es posible cambiarlo en mi código tampoco. ¿Hay un cambio sencillo de conseguir que esto funcione? Necesito una solución que es un 1-liner.
Solución
Sólo tiene que utilizar bind
. Las versiones mem_fun
son demasiado difíciles.
for_each(a.begin(), a.end(),
boost::bind(&vector<int>::push_back, boost::ref(b), _1));
Otra forma que no requiere el uso de ref
es pasar un puntero al vector que ser modificado:
for_each(a.begin(), a.end(),
boost::bind(&vector<int>::push_back, &b, _1));
Otros consejos
Este problema se explica en "excepcional estilo C ++" por Herb Sutter, página 28-30. Uno probablemente no puede crear de forma segura un puntero a un método vector<int>::push_back
ya que se necesita para estar seguro de la firma exacta de la función miembro, que puede no ser evidente incluso para vector<int>::push_back
en biblioteca estándar. Esto se debe a que (en la Biblioteca Estándar):
- Una firma miembro de la función con parámetros por defecto podría ser reemplazado por "dos o más funciones miembro firmas con un comportamiento equivalente.
- Una firma miembro de la función puede tener parámetros adicionales en default.
Al final, Herb Sutter informó que
- Uso mem_fun, pero no con la biblioteca estándar
- Uso punteros a funciones miembro, pero no con la biblioteca estándar
Sé que usted ha dicho que no desea utilizar back_inserter
, probablemente debido a que usted ha dado solo código de ejemplo simplificado.
Para cualquier otra persona preguntando cómo hacer exactamente lo que estás tratando de hacer, y feliz de utilizarlo, el uso back_inserter
:
std::copy(a.begin(), a.end(), std::back_inserter(b));
Dicho esto, siempre hay other_mem_fun
, que cocinaba antes de que sabía de impulso. Esto podría encajar.