decltype — инициализация мультимножества с пользовательской функцией сравнения в переполнении стека

Рассмотрим следующую функцию сравнения:

bool compare(std::shared_ptr<myObject> &lhs, std::shared_ptr<myObject> &rhs){
return lhs->value < rhs->value;
}

Теперь идея инициализировать мультимножество типа std::shared_ptr<myObject> который упорядочивает элементы с вышеуказанной функцией. Итак, из книги, которую я прочитал, это должно быть сделано так:

std::multiset<std::shared_ptr<myObject>, decltype(compare)*> myset{compare};

ВОПРОС:

Мой вопрос в том, что в объявлении я понял, что указатель функции передается для ссылки на функцию сравнения, но почему мы инициализируем множество с {сравнивать} ?? в чем его важность и почему так нужно делать ??

7

Решение

Потому что для работы с множеством необходим функтор сравнения. Если вы не укажете один, он будет создан по умолчанию. В этом случае, поскольку вы используете тип указателя на функцию, созданный по умолчанию тип будет нулевым указателем, который не может быть вызван; поэтому вместо этого вы должны предоставить правильный указатель функции во время выполнения.

Лучшим подходом может быть использование типа класса функции (типа функтора a.k.a.); тогда вызов функции может быть разрешен во время компиляции, и созданный по умолчанию объект будет делать правильные вещи:

struct compare {
bool operator()(std::shared_ptr<myObject> &lhs,
std::shared_ptr<myObject> &rhs) const {
return lhs->value < rhs->value;
}
};

std::multiset<std::shared_ptr<myObject>, compare> myset;
7

Другие решения

Компаратор, передаваемый в шаблон, должен быть типом того, что может быть вызвано с помощью оператора вызова функции. Это может быть либо класс, перегруженный этим оператором, либо тип лямбда-выражения или указатель на функцию. В cunstrutor set, экземпляр этого типа должен быть передан. Так decltype(compare)* тип указателя на функцию, и &compare указатель на функцию

1

decltype(compare)* в параметре шаблона указывается тип компаратора. Это не говорит который Функция должна быть использована — будь то compare, foo, bar или что-то другое. Следовательно, параметр конструктора.

1

Чтобы получить доступ к вашим элементам, вам нужно предоставить функцию для строгий слабый порядок для вашего типа.

std::multiset иметь следующий конструктор:

 explicit multiset (const key_compare& comp = key_compare(),
const allocator_type& alloc = allocator_type());

Как вы можете видеть, вы можете сделать это, передав comp указатель функции (или функциональный объект) на конструктор.


1
По вопросам рекламы [email protected]