Всегда предпочитайте set <T, less <>> для установки <T>, так как С++ 14?
#include <set>
#include <string>
#include <string_view>
using namespace std;
int main()
{
string_view key = "hello";
set<string> coll1;
coll1.find(key); // error
set<string, less<>> coll2;
coll2.find(key); // ok since C++14
}
Тогда, если это правило:
Всегда предпочитайте set<T, less<>>
set<T>
, так как С++ 14?
Ответы
Ответ 1
Тривиально найти контрпример:
#include <set>
#include <string>
using namespace std;
struct converts_to_string {
operator string() const { return ""; }
};
int main()
{
converts_to_string key;
set<string> coll1;
coll1.find(key); // OK
set<string, less<>> coll2;
coll2.find(key); // error
}
Ответ 2
При использовании associative_container<T, less<>>
может наблюдаться снижение производительности: рассмотрите тип типа
#include <iostream>
#include <set>
#include <string>
struct stupid_string
{
stupid_string(char const* s)
: s(s)
{ std::cout << "copy\n"; }
stupid_string(char const* s, int) // silent
: s(s)
{}
friend bool operator<(stupid_string const& lhs, stupid_string const& rhs);
private:
std::string s;
};
bool operator<(stupid_string const& lhs, stupid_string const& rhs) {
return lhs.s < rhs.s;
}
int main() {
std::set<stupid_string, std::less<>> s;
s.emplace("hello", 0);
s.emplace("world", 0);
s.emplace("foobar", 0);
std::cout << "find\n";
(void)s.find("test");
}
Здесь приложение operator<
в алгоритме, выполняемом s.find
, будет неявно преобразовывать литерал символа в stupid_string
. Это происходит для каждого проведенного сравнения! Живая демонстрация
Я знаю один случай, когда что-то подобное произошло в производственном коде с несоответствующей реализацией С++ 03 StdLib.
Это, кстати, основная причина, по которой неоднородный поиск через less<>
был сделан opt-in; см. N3657:
Стефан Т. Лававей предположил, что две проблемы сохранения существующее поведение и возможность гетерогенного поиска могут быть как решаются путем определения контейнеров, когда объект сравнения принимает неоднородные аргументы и только условно перегружает текущие функции поиска с версиями шаблонов.