Mixin templates accessing mixed out scope

Prudence via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Sep 12 10:36:23 PDT 2015


On Saturday, 12 September 2015 at 17:11:04 UTC, anonymous wrote:
> On Saturday 12 September 2015 16:30, Ali Çehreli wrote:
>
>> Reduced:
> [...]
>> Error: type SingleStore is not an expression
>
> Reduced further:
>
> ----
> class MyStore
> {
>     class SingleStore
>     {
>         static void New() // Removing 'static' compiles
>         {
>             new SingleStore();
>         }
>     }
> }
> ----
>
> And now the problem can be spotted:
>
> SingleStore is a nested class. That means, instances of it are 
> bound to MyStore instances. But New is static, so it doesn't 
> have a MyStore to which it could attach the `new SingleStore`.
>
> That error message is pretty awful. I filed an issue: 
> https://issues.dlang.org/show_bug.cgi?id=15049
>
like most D errors ;/ it's the #1 problem I'm struggling with in 
D. Remember there's another error with remove, that isn't 
releated to SingleStore.

> As for a fix: I guess SingleStore isn't supposed to be a nested 
> class. Mark it static then.

NO! That is the whole point!

SingleStore is a momento that wraps the key value pair, e.g.,

auto t = DeleteStore.New("mycooldelegate", (int x) { return true; 
});

t is suppose to be a single store.

then

t.Remove();

removes the delegate from the store.

Note I don't have to know the actual key or delegate!! Which is 
the whole point!

Else it would lool like this:

store[][string] mydelegatestore;

auto dg = (int x) { return true; };
mydelegatestore["mycooldelegate"] ~= dg;

then

mydelegatestore["mycooldelegate"].remove(d => dg == d);

which requires remembering both the key and the delegate, which 
makes using inline lambdas infeasible(because you'll never be 
able to remove them).

I see no reason why SingleStore has to be static. The mixin 
template should insert all that stuff into the class, which, by 
the way, works...

I've also used that New pattern all that time and it works, maybe 
not for nested classes. Moving SingleStore outside the template 
works.



I've fixed the issue with that, it's not as pretty but works. 
Still have the remove error:








import std.stdio;
import std.concurrency;



extern (C) int getch();
import std.string;
import std.concurrency;
import core.time;
import core.thread;
import std.container.array;
import std.typecons;







public class SingleStore(TKey, TValue)
{
	public TValue Value;
	public TKey Key;	
	public TValue[][TKey] Store;
	public auto Remove()
	{
		import std.algorithm;
		remove!(c => Value == c")(Store[this.Key], 
SwapStrategy.unstable);	 // Not working, can't disambiguate
	}

	public static auto New(TKey k, TValue v, ref TValue[][TKey] s)
	{
		auto o = new SingleStore!(TKey, TValue)(k, v);	
		o.Store = s;
		return o;
	}

	private this(TKey k, TValue v)
	{
		Key = k;
		Value = v;
	}
}

public mixin template ObjectStore(TKey, TValue)
{
	public static TValue[][TKey] store;

	public static auto New(TKey k, TValue v)
	{
		(store[k]) ~= v;
		auto o = SingleStore!(TKey, TValue).New(k, v, store);
		o.store = store;
		return o;
	}


}


class MyStore
{
	mixin ObjectStore!(string, bool delegate(int));

	
}

void main()
{
	auto s = MyStore.New("x", (int x) { return true; }); // works, 
stores delegate in MyStore
	
	s.Remove();  // Doesn't work because std.algorithm's remove 
isn't working

	getch();
}

(The whole point of nesting was so I wouldn't have to explicitly 
create a pointer to the store in SingleStore. Should have worked, 
probably another one of D's bugs)







More information about the Digitalmars-d-learn mailing list