Templated operator overloading
XavierAP
n3minis-git at yahoo.es
Wed Aug 22 11:58:25 UTC 2018
I've been trying some things to template operator overloads. The
reason is that I want very similar code for different types, but
I can't use polymorphism, as they're structs rather than classes.
Perhaps this choice is not as advantageous as I think, and I may
change this design from structs to classes, or else the code
duplication would be small and never subject to change. But now
I'm just trying for the sake of learning to find out what works
or not in terms of templated operator overloading, and whether
the reason something doesn't work is by design and if mentioned
in the specification, or just an arbitraty result of some
unspecified parsing/lowering step order, or it depends on the
compiler (I'm using dmd).
Since there are in my case two similar types (below just a
minimal dumb proof of concept), I want the operator(s) to work
within the same type, or also with the other. The following code
actually works, including type parameter inferrence, and const
ref to avoid struct copying:
/********************/
import std.stdio;
struct S1
{
void opOpAssign(string op, T)(const ref T x)
{
writeln(this, op, x);
}
}
struct S2
{}
void main()
{
S1 s1;
S2 s2;
s1 *= s2;
}
/********************/
When I want to have the same operator overloading code in both
types however, I can't make it work:
/********************/
private mixin template operator(Tthis)
{
void opOpAssign(string op, T)(ref Tthis, const ref T x)
{
writeln(this, op, x);
}
}
struct S1
{
mixin operator!S1;
}
struct S2
{
mixin operator!S2;
}
void main()
{
S1 s1;
S2 s2;
s1 *= s2; // Error: s1 *= s2 is not a scalar
s1.opOpAssign!"*"(s2); // Error: template
test.S1.operator!(S1).opOpAssign cannot deduce function
}
/********************/
And a final try with a global templated function instead of a
mixin template:
/********************/
private void opOpAssign(string op, Tthis, T)(ref Tthis that,
const ref T x)
{
writeln(that, op, x);
}
struct S1
{}
struct S2
{}
void main()
{
S1 s1;
S2 s2;
s1 *= s2; // Error: s1 *= s2 is not a scalar
s1.opOpAssign!"*"(s2); // OK!
}
/********************/
More information about the Digitalmars-d-learn
mailing list