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.

¿Fue útil?

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

  1. 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.
  2. Una firma miembro de la función puede tener parámetros adicionales en default.

Al final, Herb Sutter informó que

  1. Uso mem_fun, pero no con la biblioteca estándar
  2. 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.

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