#Help needed with custom iterator class for container wrapper

28 messages · Page 1 of 1 (latest)

reef patrol
#

I am trying to write a wrapper around a container that is a bidirectional range and is able to store smart pointers. As a result, I want to write the wrapper and iterator for the same. The class does not work properly, and its mostly because I lack adequate knowledge. So currently, forEach loop works, but any_of does not compile. So help needed in pointing out problems, and maybe pointing towards some resources that might help.

wicked boughBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

reef patrol
#

I wrote the main function just to test compilation. any_of does not compile, throwing error that it cannot find __begin for the container, that the container does not support:-

royal halo
# reef patrol I wrote the main function just to test compilation. any_of does not compile, thr...

that's not quite what the error excerpt complains about, but eh, close enough I guess?
like the closest mention of some __begin in that excerpt is const ranges::__access::_Begin at the end, so I assume you're referring to a different compiler/configuration when you say __begin
assuming that __begin and that other _Begin have somewhat similar roles in either standard library, you're likely looking at the wrong part of the error message

the error you have is that std::ranges::any_of doesn't work out, because there were no valid overloads found for the set of arguments you provided
the way that kind of error is structured, is that the compiler lists all the candidates it is aware of in the context of the call, and provide explanations for why the overload was discarded (when all are discarded, when the error is due to ambituity between multiple overloads it's phrased differently)
the section talking about _Begin explains why an overload you don't care about has failed, so you should focus on the other section

#

in your code, you wrote std::ranges::any_of(cont.begin(), cont.end(), [](auto t){ return true;}); so you specifically do not "care" about
overload 2 (in the error) operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
you care about overload 1 (in the error) operator()(_Iter __first, _Sent __last,
note that the rest of the signature is cutoff in the error, but the point is you passed in begin/end, not the range directly

#

so the next part is looking at why that overload 1 was not eligible/valid, which the compiler explains a little here

/opt/compiler-explorer/gcc-14.2.0/lib/gcc/x86_64-linux-gnu/14.2.0/../../../../include/c++/14.2.0/bits/ranges_algo.h:104:14: note: because 'utility::c_container<std::basic_string<char>, std::weak_ptr>::c_iterator<>' does not satisfy 'input_iterator'
  104 |     template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
      |              ^
/opt/compiler-explorer/gcc-14.2.0/lib/gcc/x86_64-linux-gnu/14.2.0/../../../../include/c++/14.2.0/bits/iterator_concepts.h:656:10: note: because 'utility::c_container<std::basic_string<char>, std::weak_ptr>::c_iterator<>' does not satisfy 'indirectly_readable'
  656 |       && indirectly_readable<_Iter>
      |          ^
/opt/compiler-explorer/gcc-14.2.0/lib/gcc/x86_64-linux-gnu/14.2.0/../../../../include/c++/14.2.0/bits/iterator_concepts.h:553:9: note: because 'remove_cvref_t<c_iterator<false, false>>' (aka 'utility::c_container<std::basic_string<char>, std::weak_ptr>::c_iterator<>') does not satisfy '__indirectly_readable_impl'
  553 |       = __detail::__indirectly_readable_impl<remove_cvref_t<_In>>;
      |         ^
/opt/compiler-explorer/gcc-14.2.0/lib/gcc/x86_64-linux-gnu/14.2.0/../../../../include/c++/14.2.0/bits/iterator_concepts.h:537:19: note: because 'same_as<iter_reference_t<const _In>, iter_reference_t<_In>>' would be invalid: constraints not satisfied for alias template 'iter_reference_t' [with _Tp = const utility::c_container<std::basic_string<char>, std::weak_ptr>::c_iterator<>]
  537 |         requires same_as<iter_reference_t<const _In>,
      |
#

you get 4 notes

  • your iterator type does not satisfy the concept input_iterator,
  • because it does not satisfy the concept indirectly_readable,
  • because it does not satisfy "implementation details" of indirectly_readable,
  • because it does not satisfy same_as<iter_reference_t<const _In>, iter_reference_t<_In>> where _In is a placeholder for your iterator type
reef patrol
#

So, it is because the iterator to const T and T are different, hence the error?

royal halo
#
        template <bool is_const = false, bool is_reverse = false>
        class c_iterator
        {
        public:

            auto operator*() -> reference;
            auto operator->() -> pointer;

        };

these are wrong

royal halo
#

because your iterator type cannot be dereferenced when constant

reef patrol
royal halo
#

because you required that it can only be used when non-const

reef patrol
reef patrol
royal halo
#

that means you can only use *obj when obj is non-const

#

and you cannot do *std::as_const(obj)

#

or *const_obj

royal halo
#

if this isn't clear to you, "is const" governs the difference in behaviour between T* and T const*

#

the problem I'm talking about is between T* and T* const

#

you could change T to be U const and it would still be a problem (U const* vs U const* const)

reef patrol
#

Ah, got it

#

My bad

wicked boughBOT
#

This question is being automatically marked as stale.
If your question has been answered, type !solved.
If your question is not answered feel free to bump the post or re-ask.
Take a look at !howto ask for tips on improving your question.

reef patrol
#

!solved