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