Validate an object within set, list, map

4
class Coordenada(){
    int fila;
    int columna;
    //los getter and setter
}

int main(){
   std::set<Coordena> coordenadaSet(Coordenada(4,6));
   Coordenada coordenada(5,6);
   if(coordendaSet.find(coordenada) != coordenadaSet.end()){
        cout << "encontro";
   } else{
        cout << "fallaste";
   }

   return 0;
}

The question of this example is to know how I can compare objects, and try to do it with operator overload to the coordinate "operator == o operator!=" some knows how to do it. Thanks.

    
asked by neoprox 08.10.2018 в 11:10
source

2 answers

5

link

template<
  class Key,
  class Compare = std::less<Key>,
  class Allocator = std::allocator<Key>
> class set;
  

Sorting is done using the key comparison function Compare. Search, removal, and insertion operations have logarithmic complexity

That is, the implementation of set does not use == or != (which is logical because if the operations have logarithmic complexity is that internally the data is ordered, and == or != no they serve to order).

To define Compare , you can create a functor , a struct that defines the operator () .

struct ComparadorCoordenada {
  bool operator() (const Coordenada& izq, const Coordenada& der) const {
    if (izq.fila < der.fila) {
      return true;
    }
    if (izq.fila > der.fila) {
      return false;
    }
    return izq.columna < der.columna;
  }
};

set<Coordenada, ComparadorCoordenada> miSet;

Update

Seeing that Compare had a default value std::less , I was curious and I checked the documentation , which tells me:

  

Unless specialized, invokes operator < on type T.

That is, it is enough to overload the operator < so that the set works, without needing a functor.

Moral: Always read the documentation.

    
answered by 08.10.2018 в 11:48
3

You were on the right track, the find function can help you; but if you want to generalize the search for any container (set, list or map) you should consider using generic functions such as std::find :

template <typename contenedor_t, typename valor_t>
bool contenedor_contiene(const contenedor_t &contenedor, const valor_t &valor)
{
    return std::find(std::begin(contenedor), std::end(contenedor), valor) != std::end(contenedor);
}

You can use the above code with any non-associative container:

std::set<Coordenada>       s{{1,2}, {3,4}, {5,6}, {7,8}, {9,0}};
std::list<Coordenada>      l{{1,2}, {3,4}, {5,6}, {7,8}, {9,0}};
std::vector<Coordenada>    v{{1,2}, {3,4}, {5,6}, {7,8}, {9,0}};
std::array<Coordenada, 5>  a{{{1,2}, {3,4}, {5,6}, {7,8}, {9,0}}};
Coordenada                 c[]{{1,2}, {3,4}, {5,6}, {7,8}, {9,0}};

std::cout << contenedor_contiene(s, Coordenada{0,9}); // Falso
std::cout << contenedor_contiene(s, Coordenada{9,0}); // Verdadero
std::cout << contenedor_contiene(l, Coordenada{0,9}); // Falso
std::cout << contenedor_contiene(l, Coordenada{9,0}); // Verdadero
std::cout << contenedor_contiene(v, Coordenada{0,9}); // Falso
std::cout << contenedor_contiene(v, Coordenada{9,0}); // Verdadero
std::cout << contenedor_contiene(a, Coordenada{0,9}); // Falso
std::cout << contenedor_contiene(a, Coordenada{9,0}); // Verdadero
std::cout << contenedor_contiene(c, Coordenada{0,9}); // Falso
std::cout << contenedor_contiene(c, Coordenada{9,0}); // Verdadero

For associative containers you must specify where to look for the value, I assume that it is in the value (not in the key):

template <typename contenedor_asociativo_t, typename valor_t>
bool contiene_en_valor(const contenedor_asociativo_t &contenedor, const valor_t &valor)
{
    return std::find_if(std::begin(contenedor), std::end(contenedor),
                        [&](auto &kv) { return kv.second == valor; }) != std::end(contenedor);
}

You can use the above code with associative containers:

std::map<int, Coordenada> m;
m.insert({0, {1,2}});
m.insert({0, {3,4}});
std::cout << contiene_en_valor(m, Coordenada{4,3}); // Falso
std::cout << contiene_en_valor(m, Coordenada{3,4}); // Verdadero

The examples assume that Coordenada has an equity operator ( == ).

    
answered by 08.10.2018 в 16:22