Как написать собственный итератор прямого диапазона, работающий с диапазонами C++20C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Как написать собственный итератор прямого диапазона, работающий с диапазонами C++20

Сообщение Anonymous »

Мой первоначальный вопрос
Как написать класс 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)) {

}
Здесь мы притворяемся, что myClass имеет тип const MyFacadeClass, определенный ранее в коде.
Разъяснение перечисленных вопросов было бы неплохо. Заранее спасибо!

Подробнее здесь: https://stackoverflow.com/questions/790 ... c20-ranges
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»