станд :: установлен. Пользовательский набор наборов

Слово.

У меня есть структура, содержащая одно поле, которое я хотел бы установить для сравнения и эквивалентности, и другие поля в качестве метаданных:

struct read_tag{
unsigned int read_id; // want std::set to use this
int offset;           // metadata
bool orientation;     // metadata
};

У меня есть функтор, чтобы сделать работу:

struct read_tag_compare {
bool operator() (const read_tag &a, const read_tag &b) const {
return a.read_id > b.read_id
}
};

и декл. необходимый набор как

std::set<read_tag, read_tag_compare> block;

Пока что все компилируется. Проблема ниже:

Как мне сделать набор, содержащий std::set<read_tag, read_tag_compare>, Я хочу что-то вроде этого:

std::set< std::set<read_tag, read_tag_compare> > blocks;
blocks.insert(a_block); // comp error

Но это дает мне очень большую и трудную для расшифровки ошибку.

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

Например

std::set<std:set<unsigned int>> set_o_sets;

работает нормально, без меня, чтобы определить, как сравнивать std::set<unsigned int>

Любая помощь приветствуется: D

0

Решение

<Сравнение по std::set использования std::lexicographical_compare без компаратора, то есть он просто пересылает < на тип элемента. (Это ограничение стандартной библиотеки, поскольку она определена для всех контейнеров, а не только для упорядоченно-ассоциативных.) Итак, вам нужен собственный компаратор для наборов наборов, который использует корректную перегрузку лексикографического сравнения:

using read_tag_set = std::set<read_tag, read_tag_compare>;

struct read_tag_set_compare {
bool operator()(const read_tag_set &a, const read_tag_set &b) const noexcept {
return std::lexicographical_compare(a.begin(), a.end(),
b.begin(), b.end(), a.key_comp());
//                                                      ^^^^^^^^^^^^
}
};

Теперь используйте: std::set<read_tag_set, read_tag_set_compare>


Код показывает, почему не существует очевидного «исправления» к упорядоченным ассоциативным контейнерам, которое могло бы сделать это «просто работающим»: если контейнеры используют пользовательские предикаты с сохранением состояния, то в общем случае не гарантируется, что члены двух отдельных контейнеров могут на самом деле сравнивать друг с другом вообще. Все, что вы знаете, это то, что элементы в один контейнер сопоставим с компаратором этого контейнера. Поэтому, когда вы используете собственный компаратор, вам лучше также четко указать, как соотносятся два разных контейнера, и вы явно утверждаете, что имеет смысл сравнивать два контейнера.

3

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

Он скомпилирован без ошибок с моей g ++ — 5.3.1 Ubuntu ..

#include<set>
#include<iostream>
using namespace std;

struct read_tag{
unsigned int read_id; // want std::set to use this
int offset;           // metadata
bool orientation;     // metadata
};
struct read_tag_compare {
bool operator() (const read_tag &a, const read_tag &b) const {
return a.read_id > b.read_id;
}
};
struct read_compare {
bool operator() (const set<read_tag, read_tag_compare> &a, const     set<read_tag, read_tag_compare> &b) const {
return true;
}
};

int main()
{
set<read_tag, read_tag_compare> block;
set<set<read_tag, read_tag_compare>, read_compare> blocks;
blocks.insert(block)
}

Выше было то, что я составил.

0

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