
On 12/18/24 12:12, Ivan Matek via Boost wrote:
Existing Practice We have std::basic_string<CharT,Traits,Allocator>::starts_with std::basic_string_view<CharT,Traits>::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<Key,Compare,Allocator>::contains std::map<Key,T,Compare,Allocator>::contains std::unordered_set<Key,Hash,KeyEqual,Allocator>::contains std::unordered_map<Key,T,Hash,KeyEqual,Allocator>::contains std::multiset<Key,Compare,Allocator>::contains std::multimap<Key,T,Compare,Allocator>::contains std::unordered_multiset<Key,Hash,KeyEqual,Allocator>::contains std::unordered_multimap<Key,T,Hash,KeyEqual,Allocator>::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.
std::list::size() had linear complexity in C++03 and std::list::empty() was constant. It was definitely a reason to have it separate from size(). contains() is a specialized algorithm that is not equivalent to `std::find() != end()` in each container's case. Historically, such specialized algorithms were implemented as members, while the generic algorithms were provided as free functions. Another such example is swap(). std::string is probably a bad example to mention in favor of member functions as it is generally agreed that it has a bloated interface.