Я кодировал класс, подобный итераторам, и по какой-то причине он не соответствует концепции Readable, как определено в Range v3. Я не знаю почему, и я пытаюсь понять, как именно мне нужно
изменить синтаксис (и семантику), чтобы выполнить концепцию.
Какие минимальные синтаксические требования для итератора должны быть читаемыми в соответствии с Range v3? Можно ли написать набор утверждений, которые должны компилироваться? (см. пример ниже)
У меня есть итератор It
, с помощью которого я могу делать базовые вещи (которые я бы назвал «читабельными»), но он не проходит проверку концепции:
#include <range/v3/all.hpp>
...
It i; // ok
typename It::value_type val = *i; // ok
typename It::reference ref = *i; // ok
typename It::value_type val2{ref}; // ok
static_assert( ranges::CommonReference<typename It::reference&&, typename It::value_type&>{} ); // ok
static_assert( ranges::Readable<It>{} ); // error: static assertion failed
Какие еще конструкции, включающие i
Я могу написать, что станет очевидным, что It
не доступен для чтения? Другими словами, какой общий код будет компилироваться только и только-если итератор Range v3-Readable?
Во многих местах написано «если он ведет себя как указатель, значит, доступен для чтения», но я не могу найти, что не так с моим итератором. Я смогу понять, что не так, когда увижу, какой код должен компилироваться?
Я пытаюсь отладить, почему мой итератор не может полностью реализовать концепцию (и поэтому отклоняется функциями range v3). Обратите внимание, что It
были std::vector<bool>::iterator
, все будет работать.
Читаемый код концепции в диапазоне v3 https://ericniebler.github.io/range-v3/structranges_1_1v3_1_1concepts_1_1_readable.html аналогичен https://en.cppreference.com/w/cpp/experimental/ranges/iterator/Readable
(я использую версию 0.5.0 [Fedora30])
template < class In >
concept bool Readable =
requires {
typename ranges::value_type_t<In>;
typename ranges::reference_t<In>;
typename ranges::rvalue_reference_t<In>;
} &&
CommonReference<ranges::reference_t<In>&&, ranges::value_type_t<In>&> &&
CommonReference<ranges::reference_t<In>&&, ranges::rvalue_reference_t<In>&&> &&
CommonReference<ranges::rvalue_reference_t<In>&&, const ranges::value_type_t<In>&>;
Похоже, что итератор должен (или может вывести) value_t<It>
, извлеченный из It::value_type
, reference_t<It>
, извлеченный из It::reference
.
Я не знаю, как rvalue_reference_t
выводится или что CommonReference
означает с точки зрения противоречий синтаксису.