Motive behind !empty() with front() instead of Optional front()
Q. Schroll
qs.il.paperinik at gmail.com
Wed Apr 7 21:31:38 UTC 2021
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`.
More information about the Digitalmars-d
mailing list