Template Base Classes, Refering to typeof(this)

Robert Jacques sandford at jhu.edu
Wed Nov 4 13:40:15 PST 2009


On Wed, 04 Nov 2009 15:31:16 -0500, Travis Boucher  
<boucher.travis at gmail.com> wrote:

> Robert Jacques wrote:
>> On Wed, 04 Nov 2009 13:35:45 -0500, Travis Boucher  
>> <boucher.travis at gmail.com> wrote:
>>
>>> I am writing a generic vector base class.  The class implements all of  
>>> the operator overloads so I don't have to implement them over and over  
>>> and over for each type of vector class.
>>>
>>> class VectorBase(size_t S, T) {
>>>     T[S] data;
>>>
>>>     ...
>>> }
>>>
>>> class Vector3f : VectorBase!(3, float) { ... }
>>>
>>> The problem I am having is implementing operations that can take a  
>>> matching vector.  I can't figure out the proper way of declaring the  
>>> type of input.
>>>
>>> eg.
>>>
>>> void opAssign(VectorBase!(S, T) r);
>>>  > function VectorBase!(3LU,float).VectorBase.opAssign identity  
>>> assignment operator overload is illegal
>>>
>>>
>>> void opAssign(this r);
>>>  > basic type expected, not this
>>>
>>>
>>> The only way I can think of handling it is to add another parameter to  
>>> the template declaration, eg:
>>>
>>> class VectorBase(size_t S, T, N) { ... }
>>> class Vector3f : VectorBase!(3, float, Vector3f) { ... }
>>>
>>> But I would like to avoid that if possible.
>>>
>>> Any hints on how to implement this so I can keep my original  
>>> declaration? class VectorBase(size_t S, T)
>>  Well first, you can't overload assignment of a class to it's own type.
>
> Ok, that makes sense, since an object is just a reference, so an  
> assignment is really just a pointer copy, not a data copy, correct?
>
>> (It's part of the language spec, at the bottom of the operator overload  
>> page IIRC) Second, I've already solved this in D2, (using structs) so  
>> let me know if you want code.
>
> Yeah, I'd be interested.  I am currently running gdc with D1, but I did  
> see some notes on getting gdc working with D2.
>
>> Third, fixed sized arrays as value-type are coming in the next release  
>> (I think), so you could wait for that. Lastly, you're (probably) going  
>> to run into issues with your other operator overloads because of some  
>> bugs in instantiating templates inside of templates using template  
>> literals as opposed to types.
>
> Do you have any hints on what to look out for?  I did implement a Vector  
> class template, passing in a template parameter to refer to the  
> instantiated type.  It used mixins.
>
> eg.
> class VectorBase(size_t S, T, N) { ... }
> class Vector3f {mixin VectorBase!(3, float, Vector3f); }
>
> It compiled and worked for the basic tests, including all operator  
> overloading.
>
> auto a = new Vector3f();
> auto b = new Vector3f(1, 2, 3);
> auto c = b * 2; // c = Vector3f(2, 4, 6)
> auto d = b + c; // d = Vector3f(3, 6, 9)
>
> I didn't run into any bugs, and even more complex methods (explict  
> methods) returned valid results (eg. T dotProduct(N vec) { ... }).

There's a bug with returning VectorBase!(S,T,N) from inside  
VectorBase(size_t S, T, N) { ... }; see the bugzilla for a test case and  
more details http://d.puremagic.com/issues/show_bug.cgi?id=2257. My first  
implementation also used mixins without any problems, I only ran into  
issues when I switched to templated functions.



More information about the Digitalmars-d mailing list