Are you asking short term, using the fully qualified syntax or long term, when we find the best way to enable omitting the class name?

Short term, even with added verbosity, which can be controlled, after all a utility class, designed to be used that way can be a single letter or two, solves naturally the problem of function chaining.
This makes proposals like UFC and the recent operator |>, as well the insane machinery behind | that std::ranges when through, unneeded. Obviously chaining is important for many if not all of us.

Also extension methods will give options to the users to fill the gap in the API of a std class. Instead of waiting years for std::string to get `contains` or optional to get `map` the users can "add it" themselves.
For some of these even the extra syntax can be acceptable (`map`, because of the chaining), for some we have to go the extra mile to be practical (`contains`).

Going the extra mile will give us a feature, people are requesting for 20 years (and has been a success in other languages for decades). 
One MASSIVE benefit of current state of affairs is that, for the first time in history, this will NOT result in UFC in any shape or form



On Fri, Jun 2, 2023 at 6:10 PM Jason McKesson via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
On Thu, Jun 1, 2023 at 10:45 AM Михаил Найденов via Std-Proposals
<std-proposals@lists.isocpp.org> wrote:
>
> Hello, with explicit object parameter we can have mixins as such:
>
> struct StringUtils {
>   template<class T>
>   void contains(this T self, char) { ... }
> };
>
> class MyString : public StringUtils {
>  ...
> }
>
> We can also have half-baked extensions as such:
>
> struct StringUtils {
>   void contains(this class MyString&  self, char);
> };
>
> class MyString : public StringUtils {
>  ...
> }
>
> void StringUtils::contains(this MyString&  self, char) { ... }
>
> This is almost usable. The fact that we need to subclass kills any perceived advantage as the extension becomes part of the implementation, making it no longer an extension.
> One is still better off writing a class-static function to get the extra functionality.
>
> This can be improved by allowing to call  StringUtils methods, which have the correct type of the `this` param or it is a template, without subclassing from it!
>
> class MyString {
>  ...
> }
>
> struct StringUtils {
>   void contains(this MyString&  self, char) { ... }
> };
>
> int main() {
>   MyString s = "hello";
>
>   s.::StringUtils::contains('e');
>
>   return 0;
> }
>
> I am using the fully qualified access to show, there is at least one syntax that is perfectly safe. It might not be very practical, but it is a start.

I see no reason to prefer `s.::StringUtils::contains('e');` when
`StringUtils::contains(s, 'e')` does the exact same thing. Why is it
important to declare `contains` as an explicit object parameter
function instead of a static member? Why is putting `s` first,
followed by gruesome syntax, preferable? What's the advantage?
--
Std-Proposals mailing list
Std-Proposals@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals