std::set
- это отсортированный ассоциативный контейнер, который предлагает быстрый поиск его элементов. Ключи вставляются в отсортированном виде, и ключи не могут быть изменены после вставки для сохранения этого порядка.
Рассмотрим следующую демонстрацию, которая создает std::set
из int*
, а затем пытается нарушить сортировку своих элементов:
#include <iostream>
#include <set>
int values[] = { 50, 40, 30, 20, 10 };
// Comparator that sorts by pointed value
struct comparator {
bool operator()(const int* left, const int* right) const {
return *left < *right;
}
};
using my_set_t = std::set<int*, comparator>;
// Checks if each of the elements of `values` are in the set
void output(const my_set_t & foo)
{
for (auto & x : values) {
std::cout << x << ' ' << foo.count(&x) << '\n';
}
std::cout << std::endl;
}
int main()
{
// Insert the address of each element of `values` into the set
my_set_t foo;
for (auto & x : values) {
foo.emplace(&x);
}
output(foo);
// Changing `values[1]` to zero should break the sorting of the set
values[1] = 0;
output(foo);
}
Вывод, который я получил:
50 1
40 1
30 1
20 1
10 1
50 1
0 0
30 0
20 0
10 0
Выражение values[1] = 0;
эффективно изменяет один из ключей set
косвенно. Это нарушает порядок и, следовательно, похоже, также нарушает count
. Я предполагаю, что это также нарушит большинство других функций set
.
Очевидно, что с кодом что-то не так. Насколько я могу судить, он следует всем правилам языка, и я не нарушаю никаких требований, которые я мог бы найти для функции сравнения или set
. Но гарантии, предоставляемые set
, тем не менее нарушены, а это значит, что я что-то упустил.