Как написать класс C++, который работает с библиотекой C++20 std::ranges?
< h3>Происхождение моей проблемы
Я пытался написать фасадный класс с итераторами на C++. Но мой компилятор (clang++18) сообщил мне, что требования не выполнены, а самое глубокое невыполненное требование: /usr/bin/../lib/gcc/x86_64-linux-gnu/14/../../. ./../include/c++/14/ranges:946:30: примечание: потому что '__adaptor::__is_range_adaptor_closure_fn(__t, __t)' будет недопустимым: нет соответствующей функции для вызова '__is_range_adaptor_closure_fn'.< /p>
Мой путь к решению этой проблемы на данный момент
Я прочитал несколько сообщений SO, включая:
- Как заставить мой пользовательский тип работать с «циклами for на основе диапазона»?
- Создание итератора с помощью концепций C++20 для пользовательского контейнера
- В чем разница между std::ranges::begin и std::begin?
- Чего мне не хватает в моем собственном итераторе std::ranges?
- Чего мне не хватает в моем собственном итераторе std::ranges?
- В чем разница между std::ranges::begin и std::begin?
- Чего мне не хватает в моем собственном итераторе std::ranges?
- Чего мне не хватает в моем пользовательском итераторе std::ranges?
- Чего мне не хватает в моем собственном итераторе std::ranges?
- В чем разница между std::ranges::begin и std::begin?
- Чего мне не хватает в моем собственном итераторе std::ranges?
- В чем разница между std::ranges::begin и std::begin?» li>
Как поддерживать адаптеры диапазона в пользовательском контейнере?
Мой новый вопросы
Пока читал принятый ответ Болова на тот последний пост, у меня возникло несколько новых вопросов:
- Почему Iterator должен быть конструируемым по умолчанию? В моей текущей реализации
это проблема, поскольку она содержит константные ссылки на большие объекты. (Это может быть разрешимо, но если нужно и как это разные вопросы.) - Зачем нужен Diffference_type, если целью является std::forward_iterator без реализации оператора-- и оператора-
Ниже приведен упрощенный пример моего класса фасада.
Код: Выделить всё
#include
#include
#include
using Set = std::unordered_set;
class MyFacadeClass {
private:
class Iterator {
public:
using iterator_category = std::forward_iterator_tag;
using value_type = std::ptrdiff_t;
Iterator(const std::ptrdiff_t self,
const Set& a,
const Set& b,
const Set::const_iterator it,
const bool inB = false) :
pSelf(self),
pA(a),
pB(b),
pIt(it),
pInB(inB) {}
std::ptrdiff_t operator*() const { return *pIt; }
bool operator!=(const Iterator& other) const { return pIt != other.pIt; }
Iterator& operator++() {
if (pInB) {
++pIt;
return *this;
}
else {
do {
++pIt;
if (pIt == pA.end()) {
pIt = pB.begin();
pInB = true;
return *this;
}
} while (*pIt == pSelf);
return *this;
}
}
private:
const std::ptrdiff_t pSelf;
const Set& pA;
const Set& pB;
Set::const_iterator pIt;
bool pInB;
};
static_assert(std::forward_iterator);
public:
Iterator begin() const { return Iterator(self, pA, pB, pA.begin()); }
Iterator end() const { return Iterator(self, pA, pB, pB.end()); }
private:
const std::ptrdiff_t self;
const Set& pA;
const Set& pB;
};
Было бы неплохо использовать синтаксис C++, например
Код: Выделить всё
for(const std::ptrdiff_t& member : myClass | std::views::filter(CONDITION)) {
}
Разъяснение перечисленных вопросов было бы неплохо. Заранее спасибо!
Подробнее здесь: https://stackoverflow.com/questions/790 ... c20-ranges
Мобильная версия