c++11 | STL | set,multiset | przeciążenie operator() dlaczego?

0

Mając kontener std::set natrafiłem na

operator ()

który przeciążam i nie rozumiem dlaczego akurat ten a nie operator<

 jak było w przypadku std::list. 

Nigdzie nie mogę znaleźć odpowiedzi dlaczego akurat operator () przeciążamy przy kontenerze std::set. 

PS Moje pytanie jest trudne bo do końca sam nie wiem o co mi chodzi, po prostu zastanawiam sie co robi operator () w klasie std::set. 

Dziękuję za odpowiedz.
3

Możesz przeciążyć operator <. std::set używa std::less jako domyślnego komparatora, który to z kolei używa operator <. Jednak jako funkcję porównującą (komparator) możesz podać cokolwiek, w tym jakiś operator ().

Może pokaż jakiś konkretny kod, którego dotyczy pytanie?

0
class Sortt
{
    public:
        bool operator() (const int& lf, const int& rf)
        {
            return (lf>rf);
        }
};

int main()
{
	std::set<int,Sortt> sinter;
}

Moze to zbyt proste pytanie ale dlaczego sortowanie umieszcza sie akurat w < >?
Rozumiem ze juz na początku wstawiania elementów trzeba ja sortować (drzewo binarne)

2

Operator () to taki stworek, który pozwala na traktować obiekt jak funkcję. Przykład:

#include <cstdio>

class c
{
public:
  c() : n(0) {}
  int operator()(int i) { n += i; return n; }
  int n;
};

int main()
{
  c o;
  printf("%d\n", o(5));
  printf("%d\n", o(7));
  return 0;
}

std::sort po prostu używa Twojego obiektu jako tzw funktora, który jest wołany własnie przez operator()

6
Michalcpp944 napisał(a):

Moze to zbyt proste pytanie ale dlaczego sortowanie umieszcza sie akurat w < >?

http://en.cppreference.com/w/cpp/container/set

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

Czyli o typie set decyduje nie tylko typ elementu, ale również komparator i alokator. Jeżeli nie podajesz komparatora i alokatora to są używane domyślne (odpowiednio less<> i allocator<>), ale one zawsze tam są. Inaczej mówiąc

set<int, Sortt>     //  set<int, Sortt, allocator<int>>

i

set<int>             // set<int, less<int>, allocator<int>>

to 2 różne typy

W tym przypadku Sortt to komparator, a komparator jest używany właśnie poprzed operator(). Innymi słowy, przeciążasz operator() komparatora, a nie kontenera set.

Innym sposobem zamiast podania własnego komparatora jest przeciążanie operator< dla typu elementu

bool operator<(int a, int b)

</del>dzięki czemu less<> będzie mógł używać naszego operatora (to jest możliwe tylko dla typów własnych i enumów).

0
class Contacts
{   
        std::string NAME;
        std::string SNAME;
        std::string NUMBER;
    public:
        Contacts(std::string NN, std::string SNN, std::string NUM)
            :NAME(NN)
            ,SNAME(SNN)
            ,NUMBER(NUM)
        {} 
        virtual ~Contacts(){}
        
        }
        bool operator < (const Contacts& itt) const        // NIE WIEM DLACZEGO ALE "const" w tym miejscu jest na tyle wazny ze bez "const"
 									      //program sie nie kompiluje 
        {
            return (this->NAME < itt.NAME);
        }

};

int main()
{
    std::set<Contacts> app_contacts;
    app_contacts.insert(Contacts("Ala","Gaj","782345677"));
}
 

Dlaczego "const" w tym miejscu jest tak ważny ze kompilator protestuje w przypadku jego braku w momencie kompilacji?

3

Ponieważ set (i map dla kluczy) traktuje elementy jako niezmienialne. Modyfikacja elementu może zagrozić unikalności i utrzymaniu sortowania.

5

std::less przyjmuje swoje argumenty jako const T &, czyli przez referencję za pomocą której nie można modyfikować obiektu. Ponieważ później używany jest operator < do porównywania, to w klasie musi on być const.

1 użytkowników online, w tym zalogowanych: 0, gości: 1