task! with a static template method gives "null this"

Ali Çehreli acehreli at yahoo.com
Sat Feb 23 17:09:06 PST 2013


On 02/23/2013 03:23 PM, Lee Braiden wrote:
> Hi all,
>
> I'm defining a template class with a static method, and adding a call to
> that to a taskpool.  However, when I run it, I get a "null this" error
> from parallelism.d.
>
> Here's the minimised code:
>
> class Population(GeneType)
> {
> 	alias Population!(GeneType) ThisType;
>
> 	static void breedIndividual(ThisType oldPop, ThisType newPop)
> 	{
> 		auto mom = oldPop.selectParent();
> 		auto pop = oldPop.selectParent();
>
> 		auto kid = mom.crossbreedFrom(pop);
>
> 		// chance of mutation
> 		if (uniform(0, MUTATION_CHANCE) == 0)
> 		{
> 		    auto oldFitness = kid.fitness();
> 		    kid.dna.mutate();
> 		    auto newFitness = kid.fitness();
> 		}
>
> 		newPop.lifeforms_ ~= kid;
> 	}
>
> 	ThisType evolve(TaskPool p)
> 	{
> 		...
>
> 		auto t = task!breedIndividual(this, newPop)
>
> 		...
> 	}
> }
>
>
> The actual error message is:
>
> core.exception.AssertError@/usr/include/d2/4.6/std/parallelism.d(2723):
> null this
>
>
> There is no "this" usage that I can see, in the breedIndividual()
> (static) method... EXCEPT maybe for the fact that ThisType depends on the
> template class expansion.  But that's all expanded at compile-time, and
> doesn't matter, right?
>
> So I'm not sure how to solve this.  My first thought was to move
> breedIndividual out of the class, but it does depend on ThisType, as
> defined in the class template.
>
>
> Am I right that this is what's causing the "null this" error?  If so,
> what can I do to fix it?
>
>
>
> Thanks,
>
>

The following is minimized code, which does not have any compilation errors:

import std.parallelism;
import std.random;

enum mutationChance = 1000;
alias MUTATION_CHANCE = mutationChance;

class Population(GeneType)
{
     alias Population!(GeneType) ThisType;

     static void breedIndividual(ThisType oldPop, ThisType newPop)
     {
         auto mom = oldPop.selectParent();
         auto pop = oldPop.selectParent();

         auto kid = mom.crossbreedFrom(pop);

         // chance of mutation
         if (uniform(0, MUTATION_CHANCE) == 0)
         {
             auto oldFitness = kid.fitness();
             kid.dna.mutate();
             auto newFitness = kid.fitness();
         }

         newPop.lifeforms_ ~= kid;
     }

     ThisType evolve(TaskPool p)
     {
         // ...

         auto newPop = new ThisType;
         auto t = task!breedIndividual(this, newPop);

         // ...

         return new ThisType;
     }

     ThisType selectParent()
     {
         return new ThisType;
     }

     ThisType crossbreedFrom(ThisType)
     {
         return new ThisType;
     }

     int fitness()
     {
         return 42;
     }

     struct Dna
     {
         void mutate()
         {}
     }

     Dna dna()
     {
         return Dna();
     }

     ThisType[] lifeforms_;
}

void main()
{
     auto p = new Population!int;
}

You can replace my stub functions with your code to help identify the 
problem.

Ali


More information about the Digitalmars-d-learn mailing list