Motive behind !empty() with front() instead of Optional front()

Paul Backus snarwin at gmail.com
Thu Apr 8 03:44:20 UTC 2021


On Thursday, 8 April 2021 at 02:10:55 UTC, Andrei Alexandrescu 
wrote:
> I'm not so sure. Complications arise when you pass an lvalue to 
> identity - is it to be considered of type T or ref T? There are 
> pros and cons to each, which is why C++ chose to allow both; 
> its unprecedented decltype(auto) was defined especially to be 
> part of function return type when it is to transport refness 
> out.

In the hypothetical world where `ref` is a type qualifier, `T` 
and `ref(T)` are distinct types. So if the lvalue's type were `T` 
you'd get `identity!T`, and if its type were `ref(T)`, you'd get 
`identity!(ref(T))`. If you had a non-`ref` lvalue that you 
wanted to pass by reference to a template function that takes an 
argument not declared as `ref` (or `auto ref`), you'd add an 
explicit conversion to `ref(T)` at the call site. None of this 
requires any special cases or complications.

Unfortunately, there's no way to get to this world without a 
fairly substantial breaking change. Currently, it's possible to 
use by-value and by-reference overloads to distinguish between 
rvalues and lvalues:

     void fun(int n) { writeln("rvalue"); }
     void fun(ref int n) { writeln("lvalue"); }

     int a = 123;
     fun(a); // lvalue
     fun(456); // rvalue

Making `ref` into a type qualifier would cause the rvalue 
overload to be called in both cases, since it would be an exact 
match vs. a match by implicit conversion.

Realistically, this is probably too disruptive a change for too 
little benefit, so I expect the best we'll get is a library 
`Ref!T` type, like C++'s `std::reference_wrapper`. Fortunately D 
has the tools to make such a type fairly ergonomic to use.


More information about the Digitalmars-d mailing list