Why code failed to compile for foo2?

Tejas notrealemail at gmail.com
Wed Dec 15 01:57:11 UTC 2021


On Tuesday, 14 December 2021 at 15:14:40 UTC, Steven 
Schveighoffer wrote:
> On 12/14/21 12:04 AM, Tejas wrote:
>> Is there anything wrong with the answer I posted?
>> 
>> Can you please tell me if there's anything dissatisfactory 
>> about it? I feel like it does everything the OP wants.
>> 
>> Also, am I wrong in using `Unconst` over `Unqual`? Isn't 
>> `Unqual` overkill if you just want to cast away `const`?
>
> Unqual is fine for value types, it should work in all cases.
>
> The OP's problem is that it's entirely possible to build an 
> overload set with *just* the unqualified types specified (in 
> this case, an integral type), but there's not a way to express 
> that and still have it work with IFTI.
>
> In other words, if you have a call like:
>
> ```d
> const int x;
> foo2(x);
> ```
>
> You want to have the parameter be mutable inside foo2. There 
> currently isn't a way to express that if `foo2` is an IFTI 
> template. The opposite is actually easily expressable:
>
> ```d
> void foo2(T)(const(T) val)
> {
>    // only one instantiation of foo2 per const(int), 
> immutable(int), int,
>    // and now val is const, even if the argument is not
> }
> ```
>
> With a standard function it works just fine due to implicit 
> conversion, but with IFTI, there's no way to express it because 
> it goes through an alias. The closest you can come is to write 
> a wrapper shim that calls the right instantiation. This should 
> be OK as long as inlining is happening, but it seems like extra 
> work for the optimizer, when it should be easy to express in 
> the language somehow.
>
> BTW, there is a related issue: 
> https://issues.dlang.org/show_bug.cgi?id=1807
>
> -Steve

Yeah, now I understand he's trying to reduce number of 
instantiations.

In that case, I'd use `inout`, but it'd be the same as your case 
: can't modify the argument anymore.

But we can pass that to another function that accepts `ulong` (as 
that seems to be the OP's usecase anyways), which can then modify 
it :D

```d
import std.traits : Unconst;
import std.stdio : writeln;

void foo2(T)(inout(T) x) if(is(Unconst!(T) : ulong)) {//You don't 
need Unqual for this
	pragma(msg, T.stringof);
	foo3(x);
}

void foo3(ulong param){
	writeln(param, " before");
	param +=10;	
	writeln(param, " after"); // can also modify params now
}
void main(){
	import std.math;
	const int ci = -3;
	int i = -2;
	immutable int ii = 24342;
	foo2(abs(ci));
	foo2(abs(i));
	foo2(ii);
	
	byte b = 0;
	const byte cb;
	immutable byte ib;
	foo2(b);
	foo2(cb);
	foo2(ib);
	
	const long cl = 4554;
	long l = 12313;
	immutable long il = 3242343;
	foo2(cl);
	foo2(l);
	foo2(il);
	
}
```


More information about the Digitalmars-d-learn mailing list