
On Tue, 17 Dec 2024 at 16:20, Alexander Grund via Boost < boost@lists.boost.org> wrote:
Working with ranges is an interesting idea, and comparisons to std::ranges::find might encounter obstacles. I presume that the OP was talking about returning an optional value given the key. This presumes an associative container. Why limit this to associative containers? A generic version can search a std::vector as well as a std::set or boost::unordered_map You just need to dispatch to either container.find or fallback to std::find
I'm just prototyping something to explain my mental model clearly. There is
a little more to it than just container.find or std::find because we have
std::map
I am not too familiar with ranges, is there an "associative range" concept? I do like the default value idea though, thanks for that :)
We can get what we want by using "if constexpr" and "requires" or by defining new concepts. We need to obtain the return value differently for map and set, since the expectation, I assume, is that we return the appropriate reference to the mapped_type, rather than the value_type.
Having the optional return type you get the default for free: find(...).value_or() I'm not too sure about supporting ranges: The hypothetical find function would return an optional reference.
I see no reason to force it to always return an optional reference, or anything optional. That seems to prematurely restrict the implementation. Consider sentinel values for the return, especially containers with non-null pointers, often we can return nullptr to indicate the item is not found. The proposed solution works for this common case, and many others besides, and still supports optional should one want to represent the default value in this manner.
So we have the footgun of getting dangling references already when someones does `find(build_map(), key)` We can avoid that by deleting the overload for rvalues but i guess for ranges we might not be able to easily detect an underlying temporary.
Is there a new lifetime issue given that std::ranges::find already exists and works. Our additional layer can take the default by universal reference and forward as the result? I shall post some code a little later, possibly tomorrow. Then we can debate the alternatives a little more concretely. Neil Groves