On Tue, Dec 17, 2024 at 3:08 PM Vinnie Falco wrote:
On Mon, Dec 16, 2024 at 10:46 PM Ivan Matek wrote:
On Mon, Dec 16, 2024 at 6:24 PM Vinnie Falco
wrote:
Can this be implemented as a free function over the public API of
unordered containers? In other words, this signature:
Yes, but it is not like Barry or other people
https://www.youtube.com/watch?feature=shared&t=150&v=kye4aD-KvTU
wanting member functions do not know this.
It seems there are two choices here:
1. Add a member function to uncountably many existing and future unordered
containers by adding a member function
2. Write a single, separate free function template which works for all
existing and future unordered containers
The member function requires selecting an optional type and including its
header, while the free function approach can scale to different optional
types (one per free function).
Please explain why we should prefer 1 instead of 2.
There are two related points here
1. member syntax is better for users
2. existing practice
Member Syntax is Better for Users
Herb's UFCS P3021
https://open-std.org/JTC1/SC22/WG21/docs/papers/2023/p3021r0.pdf has a
list of reasons explaining this in detail. Since some people mentioned UFCS
here before just to make clear: I am linking this paper *not* because of
UFCS, but because it explains why
member syntax is better for users(sections 3.1.1, 3.1.2, 3.1.3).
Existing Practice
We have
std::basic_string::starts_with
std::basic_string_view::starts_with
although there is(or more precisely there will be)
std::ranges::starts_with
You may say that having member function 2 times is fine since it duplicated
just 2 times, but we also have
std::set::contains
std::map::contains
std::unordered_set::contains
std::unordered_map::contains
std::multiset::contains
std::multimap::contains
std::unordered_multiset::contains
std::unordered_multimap::contains
If you say this is just some modern C++ nonsense:
Since C++98 containers had empty member function although it is trivially
implementable with free function empty. Here not even talking about
"complicated" C++17 std::empty that understands C arrays/std::array/...,
talking about simple function that could just take container with size
member function.
template<typename C>
bool empty(const C& c) { return c.size() == 0; }
But for decades we have this duplication in member functions since empty is
commonly called function.
To recap situation is that in C++ we have tension between ease of use of
common operations on container vs blowing up it's API size. And as Barry
wrote 2 most common operations on map are insertion and lookup. So I
believe lookup is definitely important enough to get
nicer syntax.
few notes regarding suggested free function discussed:
1. Dispatching to member may be confusing. std::ranges::find /
std::ranges::contains does not
https://stackoverflow.com/a/75687947/ dispatch
to members if available
2. try_find seems like a wrong name. try_at makes sense since at has
precondition(unless you use exceptions for control flow :) ), while
find does
not, i.e. it can fail. So it is kind of weird to have a prefix that says
try in algorithm that has same "success rate" as find.