C++ Logo

std-proposals

Advanced search

[std-proposals] Extension methods take 2

From: Михаил Найденов <mihailnajdenov_at_[hidden]>
Date: Thu, 1 Jun 2023 17:44:51 +0300
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.
We can argue how we can improve it, what are the chances, subclasses can
have the same name and/or what happens if other utilities are already in
use. But at least with that particular syntax, no issues will ever arise.
(Of course a performance argument can be made - now after the dot, many
more classes become candidates, but it's a start...)

And no, there is no UFC proposed.
Just making use of the fact, the *explicit object parameter **already **does
not point to a separate (new, with the introduced type) state! This is *
*fundamentally** different then regular methods and the reason why this
kind of classes **do not need subclassing **to be used by other classes. *All
state is already defined by an external class, being a child of that class
does not bring a structural difference.

Received on 2023-06-01 14:45:03