I mean you could make that work in C++ too, with ref qualifier method overloads:
namespace std {
class string {
bool contains(const string& other) & {
//Check if 'this' is in 'other'
}
bool contains(const string& other) && {
//check if 'other' is in 'this'
}
};
}
using namespace std::string_literals;
int main() {
string foo("foo bar foo");
foo.contains("bar"); //returns true
"bar"s.contains("foo bar foo"); //returns true
}
But I hope not because this 'flipping the script' behavior just makes the code flow more difficult to reasonate about.
No, I guess you missed the point. Rust's contains isn't somehow magically upside down like your weird C++ example but it does work on the actual built-in string literal, whereas C++ can't do that because its built-in string literal is the weird C string literal that's a zero terminated char array for some reason.
Notice how you needed to write "bar"s to make your code compile? That trailing 's' says you want specifically to construct a std::string not use the language's built-in string literals. So you'll need a full blown hosted C++ environment (otherwise there's no allocator for the string class)
The Rust string literal was inherently a &'static str, which only needs the core language, it Just Works™.
There's a weird asymmetry, Bjarne wants user defined types to have all the features the built-in types have, but, not vice versa. So you can overload the short circuiting boolean operators on your own types (don't, this is basically always a bad idea) but you can't call methods on built-in literals like "foo" or true or 'X'...
With the string literal suffixes, I don't think it's all that different ("hello"sv.contains(username)). Yes, yes, for legacy reasons bare "" is the C-style string, but you can get a string_view string easily enough.
I agree that it's not "all that different". It's just that years later what C++ offers is slightly worse while having more awkward syntax.
Exactly like the article topic. Iterating over your maybe type was IMO an obvious thing you'd want, but it took C++ a decade to provide this behaviour in a slightly awkward way.
And likewise for their maybe reference, which C++ 26 also finally lands. The original discussion papers for std::optional explain the core ideas for std::optional<T&> but apparently the possibility that it's an assign through type, a thing nobody has ever wanted, and no other language has ever provided - was so important that it blocked all work on this idea for about a decade.