www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - minElement on array of const objects

reply Aurelien Fredouelle <aurelien.fredouelle+dlang gmail.com> writes:
Hi all,

It seems that it is not possible to use minElement on an array of 
const objects:

class A
{
   int val;
}

const(A) doStuff(const(A)[] v)
{
   import std.algorithm.searching : minElement;
   return v.minElement!"a.val";
}

This gets the following compiler error:

std/algorithm/searching.d(1256,28): Error: cannot implicitly 
convert expression (front(r)) of type const(A) to app.A
std/algorithm/searching.d(1286,35): Error: cannot implicitly 
convert expression (r[i]) of type const(A) to app.A
std/algorithm/searching.d(1258,36): Error: template instance 
std.algorithm.searching.extremum!("a.val", "a < b", const(A)[], 
A) error instantiating
std/algorithm/searching.d(3345,24):        instantiated from 
here: extremum!("a.val", "a < b", const(A)[])
source/app.d(11,11):        instantiated from here: 
minElement!("a.val", const(A)[])

Is there a reason why this is not allowed? Shouldn't minElement 
be able to return a const(A) in this situation?

Thanks,
Aurelien
Nov 13
parent reply Temtaime <temtaime gmail.com> writes:
On Monday, 13 November 2017 at 10:20:51 UTC, Aurelien Fredouelle 
wrote:
 Hi all,

 It seems that it is not possible to use minElement on an array 
 of const objects:

 class A
 {
   int val;
 }

 const(A) doStuff(const(A)[] v)
 {
   import std.algorithm.searching : minElement;
   return v.minElement!"a.val";
 }

 This gets the following compiler error:

 std/algorithm/searching.d(1256,28): Error: cannot implicitly 
 convert expression (front(r)) of type const(A) to app.A
 std/algorithm/searching.d(1286,35): Error: cannot implicitly 
 convert expression (r[i]) of type const(A) to app.A
 std/algorithm/searching.d(1258,36): Error: template instance 
 std.algorithm.searching.extremum!("a.val", "a < b", const(A)[], 
 A) error instantiating
 std/algorithm/searching.d(3345,24):        instantiated from 
 here: extremum!("a.val", "a < b", const(A)[])
 source/app.d(11,11):        instantiated from here: 
 minElement!("a.val", const(A)[])

 Is there a reason why this is not allowed? Shouldn't minElement 
 be able to return a const(A) in this situation?

 Thanks,
 Aurelien
It should not until it uses recursion to find min element. const(Class) res = ...; ... return res; Algorithm tries to assign to res variable and fails because in D const(Class) means both const object and const reference to it. So we cannot assign another reference to const(Class) variable.
Nov 13
parent reply Nathan S. <no.public.email example.com> writes:
Unqual!Element seed = r.front;
alias MapType = Unqual!(typeof(mapFun(CommonElement.init)));
This looks like a job for std.typecons.Rebindable!(const A) instead of Unqual!(const A) which is used currently. I am surprised that this is the first time anyone has run into this.
Nov 13
parent reply vit <vit vit.vit> writes:
On Monday, 13 November 2017 at 12:15:26 UTC, Nathan S. wrote:
Unqual!Element seed = r.front;
alias MapType = Unqual!(typeof(mapFun(CommonElement.init)));
This looks like a job for std.typecons.Rebindable!(const A) instead of Unqual!(const A) which is used currently. I am surprised that this is the first time anyone has run into this.
Is Unqual necessary here?: https://github.com/dlang/phobos/blob/master/std/algorithm/searching.d#L1284 https://github.com/dlang/phobos/blob/master/std/algorithm/searching.d#L1340 And here https://github.com/dlang/phobos/blob/master/std/algorithm/searching.d#L1301 https://github.com/dlang/phobos/blob/master/std/algorithm/searching.d#L1355 is necessary something like RebindableOrUnqual instead of Unqual: template RebindableOrUnqual(T){ static if (is(T == class) || is(T == interface) || isDynamicArray!T || isAssociativeArray!T)alias RebindableOrUnqual = Rebindable!T; else alias RebindableOrUnqual = Unqual!T; }
Nov 13
parent Aurelien Fredouelle <aurelien.fredouelle+dlang gmail.com> writes:
On Monday, 13 November 2017 at 14:28:27 UTC, vit wrote:
 On Monday, 13 November 2017 at 12:15:26 UTC, Nathan S. wrote:
 [...]
Is Unqual necessary here?: https://github.com/dlang/phobos/blob/master/std/algorithm/searching.d#L1284 https://github.com/dlang/phobos/blob/master/std/algorithm/searching.d#L1340 And here https://github.com/dlang/phobos/blob/master/std/algorithm/searching.d#L1301 https://github.com/dlang/phobos/blob/master/std/algorithm/searching.d#L1355 is necessary something like RebindableOrUnqual instead of Unqual: template RebindableOrUnqual(T){ static if (is(T == class) || is(T == interface) || isDynamicArray!T || isAssociativeArray!T)alias RebindableOrUnqual = Rebindable!T; else alias RebindableOrUnqual = Unqual!T; }
Thanks, I filed https://issues.dlang.org/show_bug.cgi?id=17982 to track the issue.
Nov 14