
On Sat, 21 Dec 2024, 07:21 Richard Hodges via Boost,
Sent from my iPad
On 20 Dec 2024, at 20:37, Neil Groves via Boost
wrote: On Thu, 19 Dec 2024 at 15:30, Christian Mazakas via Boost < boost@lists.boost.org> wrote:
The case against a free function gets a lot stronger once you remember that optional in C++ still supports unchecked accesses with trivial syntax and that the most ergonomic and safe way to actually use it is via something like this:
users.find(user_id).map([](auto& user) { user.status = deactivated; return user; });
As you know I've tried seeing how far I could get with some work in Boost.Range. I appreciate this isn't the solution you are dreaming of.
I have working on a private branch (without new member functions in any associative container):
users | mapped_values(user_id) | invoke([](user_type& user) { user.status = deactivated; });
How is this better than
for(auto&& user : users) if(user == user_id) deactivate(user);
?
It has been a very long thread! The original request was to add a new member function to map, a try_find which returned an optional reference. Thus users was a map and so the lookup wasnt linear and as requested in this case it worked over the mapped values. Your user would have been the key/value pair, but that is pedantic. We all agree for this task it was all far too complicated, as it often is if one is working on stripped down simple examples. The code I worked up on a branch kept the use of maps equal_range / find, while supporting linear search for other ranges and binary search of sorted. It could keep the search algorithm optimal for known containers and/or ranges based on their sorted and uniqueness guarantees. Thus it was one example of coding up our recommendations we teach, to prefer member function calls when present, to use lower_bound on sorted sequences. So in addition to solving the original problem it reduced the need to teach all the special divergent ways of performing find. That IME is a problem to teach and remember and having no unified optimal syntax for lookup is a pain sometimes in generic code. We have to know it is a map, alter the code to optimize the lookup. Ultimately though, we all ended up going in different directions and going nowhere! I think most know how the pipe operator works in Boost.Range and C++20 ranges by now. It is so frequently adopted as a consistent idiom that it is teachable and understood, at least in the sample of developers I am familiar with. It doesn't mean we have to use it and if it is easier not to I do not. It came up hete because the OP demanded left to right syntax and there is an existing adaptor solution to get mapped values already in Boost.Range and std. Thus my syntax examples were to address the OPs proposition and attempt to hit a defined optimal syntax in the problen statement. You are spot on though. This is all totally pointless. Neil