Aquí podría ser tu PUBLICIDAD


Puntero a funciones miembro - C ++ std :: list sort

votos
4

¿Cómo paso un puntero a una función de miembro a std :: list.sort ()?

es posible? Gracias

struct Node {
       uint32_t ID;
       char *   Value;
};

class myClass {
          private:
            uint32_t  myValueLength;
          public:
            list<queueNode *> MyQueue;
            bool compare(Node * first, Node * second);
            bool doStuff();
}

bool myClass::compare(Node * first, Node * second) {
    unsigned int ii =0;
    while (ii < myValueLength)
    {
        if (first-> Value[ii] < second-> Value[ii]) 
        {
            return true;
        } else if (first-> Value[ii] > second-> Value[ii])
        {
            return false;
        }

        ++ii;
    }

    return false;
}

bool myClass::doStuff()
{
    list.sort(compare);
}

Quiero usar una variable de longitud desde dentro de la clase en lugar de hacer strlen () dentro de la función de comparación (El valor siempre tendrá la misma longitud)

Editar: myValueLength no era la única variable a la que quería acceder desde la función de comparación. Simplemente la simplifiqué para acortar el ejemplo.

Publicado el 12/03/2009 a las 16:16
fuente por usuario Ben Reeves
En otros idiomas...        العربية       

6 respuestas

votos
7

Al elaborar la respuesta del duelo , ¿por qué no usar un functor? P.ej:

struct Functor
{
  bool operator()( char * a, char * b )
    { return strcmp(a,b) < 0; }
};

Entonces podrías usar:

Functor f;
myList.sort(f);

Incluso podría usar su clase como el Functor definiendo operator () ...

class myClass {
  ...
  bool operator()( queueNode * a, queueNode * b )
  { return compare( a, b ); }

  void doStuff() { MyQueue.sort(*this); }
};

Código de ejemplo simple:

#include <iostream>
#include <list>
using namespace std;

  // Assumes  TYPE t; cout << t;  is valid.
template<class TYPE>
inline ostream & operator<< ( ostream & theOstream,
                              const list<TYPE> & theList )
{
  typename list<TYPE>::const_iterator listIterator = theList.begin();
  for ( int i = 0;   listIterator != theList.end();  listIterator ++, i ++ )
    theOstream << "    [" << i << "]:   \"" << (*listIterator) << "\"" << endl;
  return theOstream;
}

struct Functor
{
  bool operator()( const char * a, const char * b )
    { return strcmp(a,b) < 0; }
};

int
main()
{
  list<char*>  l;

    /* Load up some example test data... */
  char  s[3];
  s[2] = '\0';
  for (   s[0]='c'; s[0]>='a'; s[0]-- )
    for ( s[1]='c'; s[1]>='a'; s[1]--  )
      l.push_back(strdup(s));

    /* Show us that test data... */
  cout << l << endl;

    /* Sort list. */
  Functor f;
  l.sort(f);

    /* Show us what we have now... */
  cout << l << endl;
}
Respondida el 12/03/2009 a las 05:25
fuente por usuario Mr.Ree


Aquí podría ser tu PUBLICIDAD


votos
7

Es posible. ¿Consideró usar boost :: function?

list.sort( boost::bind( &myClass::compare, this, _1, _2 ) );

¿Su función de "comparación" se basará en esta información? Si no, puede simpy hacer que la función 'comparar' sea estática . Y luego será

list.sort( &myClass::compare );

Puede agregar helper struct para hacer su comparación y luego

list.sort( Comparer( myValueLength ) );

struct Comparer
{
    Comparer( uint32_t myValueLength ):
        length( myValueLength )
    {}

    bool operator() (Node * first, Node * second)
    {
        unsigned int ii =0;
        while (ii < length)
        {
            if (first-> Value[ii] < second-> Value[ii]) 
            {
                    return true;
            } else if (first-> Value[ii] > second-> Value[ii])
            {
                    return false;
            }

            ++ii;
        }

        return false;
    }


    uint32_t length;
};
Respondida el 12/03/2009 a las 04:26
fuente por usuario Mykola Golubyev

votos
3

Es posible que desee utilizar un functor.

http://www.newty.de/fpt/functor.html

Respondida el 12/03/2009 a las 04:18
fuente por usuario grieve

votos
1

Tenga en cuenta que std::listordena el elemento de acuerdo a lo operator<definido para ese elemento. Necesita cambiar su comparefunción para usar un global operator<definido para Nodeobjetos:

bool operator<(Node const& first, Node const& second) {
unsigned int ii =0;
while (ii < length)
{
    if (first.Value[ii] < second.Value[ii]) 
    {
            return true;
    } else if (first.Value[ii] > second.Value[ii])
    {
            return false;
    }

    ++ii; 
}

return false;

}

Una mejora sugerida será:

bool operator<(Node const& first, Node const& second) {
    for (size_t ii =0; first.Value[ii] == second.Value[ii]; ++ii) ; // note ;
    return (first.Value[ii] < second.Value[ii]);
}

Si char *Valuerealmente representa una cadena de estilo C y desea una clasificación lexicográfica, es posible realizar otras mejoras:

bool operator<(Node const& first, Node const& second) {
     return (strcmp(first.Value, second.Value) < 0);
}

y si realmente son cadenas, te sugiero que uses std::stringy puedes escribir:

bool operator<(Node const& first, Node const& second) {
     return first.Value < second.Value;
}
Respondida el 12/03/2009 a las 04:23
fuente por usuario dirkgently

votos
0

¿Por qué no hacer su función de comparación estática entonces ya no es necesario el funtor. A continuación, puede hacer list.sort (comparar);

No importa ... Me acabo de dar cuenta de su función de comparación está utilizando un miembro de la clase de datos por lo que no puede ser estática. Utilice Functor :)

Respondida el 02/03/2012 a las 06:17
fuente por usuario cchampion

votos
0

Como afligido y mrree sugirió

simplemente sobrecargar el operador () funciona

Gracias a todos los que respondieron

struct Node {
       uint32_t ID;
       char     *       Value;
};

class myClass {
          private:
            uint32_t  myValueLength;
          public:
            list<queueNode *> MyQueue;
            bool operator()(Node * first, Node * second);
            bool doStuff();
}

bool myClass::operator()(Node * first, Node * second) {
    unsigned int ii =0;
    while (ii < myValueLength)
    {
        if (first-> Value[ii] < second-> Value[ii]) 
        {
                return true;
        } else if (first-> Value[ii] > second-> Value[ii])
        {
                return false;
        }

        ++ii;
    }

    return false;
}

bool myClass::doStuff()
{
    list.sort(*this);
}
Respondida el 12/03/2009 a las 05:32
fuente por usuario Ben Reeves