Motive behind !empty() with front() instead of Optional front()
Andrei Alexandrescu
SeeWebsiteForEmail at erdani.org
Thu Apr 8 02:18:23 UTC 2021
On 4/7/21 5:31 PM, Q. Schroll wrote:
> On Tuesday, 6 April 2021 at 02:14:17 UTC, Paul Backus wrote:
>> On Tuesday, 6 April 2021 at 01:47:47 UTC, Q. Schroll wrote:
>>> On Friday, 26 March 2021 at 15:12:04 UTC, Paul Backus wrote:
>>>> Of course the ideal would be to make `ref` itself into a type
>>>> qualifier (`ref(T)`).
>>>
>>> If you look at all the exceptions C++ has for its reference type
>>> constructor, you'll immediately see why Walter created `ref` as a
>>> storage class and not a type constructor. C++ reference types in many
>>> cases don't compose; e.g. `vector<int&>` isn't a thing.
>>> If you really think about it, you don't need `ref` as a type
>>> constructor. Although allowing `ref` local variables wouldn't be
>>> harmful, I guess.
>>
>> Here's what the generic identity function currently looks like in D:
>>
>> auto ref T identity(T)(auto ref T arg)
>> {
>> import core.lifetime: forward;
>> return forward!arg;
>> }
>>
>> Here's what the generic identity function *would* look like if `ref`
>> were a type qualifier:
>>
>> T identity(T)(T arg)
>> {
>> return arg;
>> }
>>
>> I rest my case.
>
> In C++, the identity function is
> ```C++
> template<typename T>
> T&& identitiy(T&& arg)
> {
> return std::forward<T>(arg);
> }
> ```
> if you want it to work like `identity(arg)`.
>
> **TL;DR:** C++ doesn't do it the simple way for a reason.
>
> If you do
> ```C++
> template<typename T>
> T identitiy(T arg)
> {
> return arg;
> }
> ```
> you get copies unless you call it `identity<int&>(arg)` and
> `identity<int&&>(1)` (which defeats the purpose, I guess.
>
> Template type deduction alone (C++ has 4 different rule sets about type
> deduction) is complicated. One reason for stripping `ref` from the
> argument types unless they explicitly bind to `ref` parameters is that
> references should act like aliases:
> ```C++
> int i;
> int& r = i;
> f(i);
> f(r);
> ```
> Here, `f(r)` should act the same as `f(i)` irrespective of how `f` is
> defined. `f` could take `int`, `int&`, `const int&`, or `T`, `const T&`,
> or `T&&` for some `T` that can implicitly constructed from `int`. For
> `int&&` or `T&`it wouldn't compile. References as type constructors are
> weird. And please note, this is what I *immediately* could come up with
> and I verified. There's stuff with function types and static array
> bounds that I remember have shenanigans with references, but I'd have to
> do some search for details.
>
> The only thing D does wrong in this regard is not having `forward` and
> `move` in `object.d`.
Very well put, thank you.
More information about the Digitalmars-d
mailing list