@nogc with opApply
tide
tide at tide.tide
Sun Aug 12 01:09:39 UTC 2018
On Saturday, 11 August 2018 at 10:00:34 UTC, Alex wrote:
> Hi all,
> maybe I misunderstand something but having this:
>
> ´´´
> import std.experimental.all;
>
> static assert(isIterable!S);
>
> void main()
> {
> S s;
> s.each!(el => el.writeln);
> }
>
> struct S
> {
> private Nullable!uint member = 0;
> Nullable!uint front() @nogc { return member; }
> //void popFront(){} // not implementable.
> //bool empty(){} // not implementable
> Nullable!uint successor(uint current) @nogc { return
> Nullable!uint.init; }
>
> /**
> the opApply method grants the correct foreach behavior
> */
> int opApply(scope int delegate(ref uint) /*@nogc*/
> operations) //@nogc
> {
> int result;
>
> for(auto leading = front; !leading.isNull; leading =
> successor(leading.get))
> {
> result = operations(leading.get);
>
> if(result)
> {
> break;
> }
> }
> return result;
> }
> }
> ´´´
>
> Everything works fine, before I try to use the opApply function
> inside a @nogc function.
>
> If I do, compiler complains, that opApply is not marked as
> @nogc. Ok.
> If I try to mark opApply @nogc, I would have to mark operations
> delegate also as @nogc, but I can't do this, as I do not know a
> priori, how it will be used.
>
> Now, as I learned at some point, a possibility would be, to
> templatify the function, as the compiler can then derive, if
> @nogc apply or not.
> But if I write
> ´´´
> int opApply()(...){...}
> ´´´
> Then the static assert from above refuses to compile.
>
> So... how to solve this case?
There's no way to solve it, just don't use @nogc is the easiest
workaround. It wasn't thought out when it was added and these are
one of the cases where it doesn't work. Having functions
automatically declare themselves @nogc if they don't use the gc
would solve part of the problem. Which is how templates work.
https://dlang.org/library/std/traits/is_iterable.html
If you see how isIterable is defined you'll see that it requires
opApply be able to provide the element type automatically. That
is "foreach" doesn't define a type and it is automatically
deduced. The compiler can't deduce the argument type because the
function is a template.
foreach(t ; S.init) // Error: cannot infer type for `foreach`
variable `t`, perhaps set it explicitly
{
}
More information about the Digitalmars-d-learn
mailing list