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
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
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:
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
.