During initializing Variant, D discards top level const of array, which
leads to little unintuitive behaviour. Consider code:
import std.stdio;
import std.variant;
void main()
{
const int[] arr;
Variant v = Variant( arr );
writeln( v.peek!( typeof( arr ) )() );
writeln( v.peek!( const(int)[] )() );
writeln( v.type() );
}
...and output:
%dmd main.d && ./main.d
null
7FFF358AE298
const(int)[]
As you can see peek works successfully not for original array type, but
for type without top level const. Is Variant supposed to work in that way ?
Comment #1 by code — 2012-07-31T13:07:32Z
Variant should generally ignore top-level const for »value types« (i.e. array slices, pointers, integral types, …).
Comment #2 by code — 2012-07-31T13:09:26Z
… the point being that this is, if anything, analogous to the constness of the Variant instance itself, not the contained type.
Comment #3 by cybevnm — 2012-08-01T12:58:14Z
(In reply to comment #2)
> … the point being that this is, if anything, analogous to the constness of the
> Variant instance itself, not the contained type.
Unfortunately, Variant's handling of arrays is different to handling of class references. So we have next situtation:
import std.variant;
class C { }
void main()
{
{
const C c;
Variant v = Variant( c );
assert( v.peek!( typeof(c) )() != null );
}
{
const C[] cs;
Variant v = Variant( cs );
assert( v.peek!( typeof(cs) )() == null );
}
}
But array top-level const cutting is understandable, it's the way it works in all other places...
Comment #4 by code — 2012-08-01T13:08:10Z
I meant that Variant should regard e.g. const(T[]) and const(T)[] or const(T*) and const(T)* equivalent, i.e. allow implicit conversion between them.
The fact that const is automatically stripped from arrays is not Variant-specific, template functions generally work like that in D.
Comment #5 by cybevnm — 2012-08-01T13:43:19Z
(In reply to comment #4)
> I meant that Variant should regard e.g. const(T[]) and const(T)[] or const(T*)
> and const(T)* equivalent, i.e. allow implicit conversion between them.
Agree, it will resolve the problem.
Comment #6 by bugzilla — 2019-10-18T12:12:52Z
This seems not to be a Phobos bug:
import std.stdio;
void main()
{
const int[] arr;
writeln(typeof(arr).stringof);
Test(arr);
}
struct Test
{
this(T)(T value)
{
writeln(T.stringof);
}
}
writes:
const(int[])
const(int)[]
For me the question remains: Is this intentional (for reasons I don't understand yet) or a language bug?
Comment #7 by code — 2019-10-18T12:17:48Z
(In reply to berni44 from comment #6)
> For me the question remains: Is this intentional (for reasons I don't
> understand yet) or a language bug?
Removal of "head const", i.e. the outer layer, is intentional. This avoid duplicate template instantiations for code that has identical semantics anyway (like for a const int parameter, where it is copied anyway even if non-const, so from the caller side, there isn't a difference), and allows range functions to work in a natural way with constness (where, again, the slice is copied anyway, so const or not isn't visible to the caller).
Comment #8 by bugzilla — 2019-10-18T19:51:14Z
(In reply to David Nadlinger from comment #7)
> Removal of "head const", i.e. the outer layer, is intentional.
OK. In that case this is a Phobos bug. The solution would be to make peek remove "head const" on the given type und check if that's the type of the Variant. I've got too few experience on const, so I cannot fix this. I tried to add a small template which returns what it get's (just out of curiosity, if that could work). With this, peek could compare the type of the returned value to the value of the Variant. But this did not work out well. Partly, because the template needs to be given a value and not a type, partly because of inout gets in the way.
I don't know if it's of much use, because this can be easily derived from the post above, but I created this unittest which currently does not pass but a corrected version of peek should pass:
unittest
{
const int[] arr;
Variant a = Variant(arr);
assert(a.peek!(typeof(arr)) !is null);
}
Comment #9 by robert.schadek — 2024-12-01T16:15:23Z