Почему это работает? std :: set find с поисковым ключом и пользовательским компаратором - PullRequest
6 голосов
/ 28 февраля 2012

Я не понимаю, почему работает следующее (хотя я рад, что оно работает!):

Я могу определить std::set объектов с помощью собственного компаратора.Этот пользовательский компаратор работает путем сравнения некоторой переменной-члена двух сравниваемых объектов. НО тогда я могу использовать set функцию .find(x) с x, имеющим тип переменной-члена, а не сам объект, и это работает!

Вот чрезвычайноупрощенный пример:

my_class.h

class my_class   //just hold an integer
{
    public:
      int an_int;

    my_class(int new_int) : an_int(new_int)
    { }


    //compare instances of this class by comparing their integers...
    struct compare_instances   
    {    
      bool operator() (const my_class &a, const my_class &b) const
      {
        return a.an_int < b.an_int;
      }
    };
};

main.cpp:

...
std::set<my_class, my_class::compare_instances> my_class_set;
my_class_set.insert( my_class(18) );
my_class_set.insert( my_class(7)  );
my_class_set.insert( my_class(22) );

std::set<my_class, my_class::compare_instances>::const_iterator found_it
                  = my_class_set.find(18);
 std::fprintf(stderr, "found_it->an_int = %d\n", found_it->an_int); 

Вывод: "found_it-> an_int = 18" !!!!!!

Я бы ожидал, что приведенный выше код не скомпилируется, и компилятор крикнул мне, что "18 не относится к типу my_class".Но это не ...

Разве аргументы .find не должны быть того же типа, что и элементы самого set?Вот что говорит документация ...

1 Ответ

12 голосов
/ 28 февраля 2012

Это работает, потому что int неявно конвертируется в ваш класс. Любой конструктор, который не помечен explicit и может вызываться только с одним аргументом, который не относится к типу самого класса, определяет неявное преобразование. Фактически это означает, что всякий раз, когда ожидается объект класса, вы также можете использовать int, и он будет автоматически преобразован.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...