F i*_*i L 19 d operator-overloading dmd gdc
有一段时间我对D'运算符重载的方向感到困惑,但现在我意识到它是一个漂亮的系统...如果它只适用于核心类型(int,float等).考虑以下代码:
struct Vector {
float X, Y;
void opOpAssign(string op)(Vector vector) {
X.opOpAssign!op(vector.X); // ERROR: no property "opOpAssign" for float
Y.opOpAssign!op(vector.Y); // ERROR: ditto
}
}
Run Code Online (Sandbox Code Playgroud)
这将是漂亮的代码,如果它工作,看到它在一个方法中重载所有+ =, - =,*=等运算符.但是,正如您所看到的,它不是开箱即用的.我用模板创建了一个解决方案(上帝,我爱D):
template Op(string op, T) {
void Assign(ref T a, T b) {
static if (op == "+") a += b;
else if (op == "-") a -= b;
else if (op == "*") a *= b;
else if (op == "/") a /= b;
}
}
struct Vector {
float X, Y;
void opOpAssign(string op)(Vector vector) {
Op!(op, typeof(X)).Assign(X, vector.X);
Op!(op, typeof(Y)).Assign(Y, vector.Y);
}
}
Run Code Online (Sandbox Code Playgroud)
这很好,只是我更喜欢把所有东西都留在"内部".有没有办法在没有模板的帮助下完成这项工作?我知道我在这里很挑剔,因为没有性能损失,在我需要这样做的情况下导入模块并不难.我只是想知道它是否内置,我忽略了一些东西.
Jon*_*vis 22
根据定义,D中的几乎所有重载运算符都是模板.请注意,void opOpAssign(string op)(Vector vector)
其模板参数是一个字符串.所以,不,你不能将它作为非模板函数重载.现在,您不需要第二个模板来执行此操作(因此,如果询问您是否需要模板,则表示辅助模板,则答案为否),但重载的运算符函数已经是模板.
做你正在尝试做的事情的规范方法是使用字符串mixins:
void opOpAssign(string op)(Vector vector)
{
mixin("X" ~ op ~ "=vector.X;");
mixin("Y" ~ op ~ "=vector.Y;");
}
Run Code Online (Sandbox Code Playgroud)
rat*_*eak 13
这意味着要与mixins结合使用
void opOpAssign(string op)(Vector vector) {
mixin("X"~op~"=vector.X;");
mixin("Y"~op~"=vector.Y;");
}
Run Code Online (Sandbox Code Playgroud)
更不用说这可以很容易地耦合到其他算术运算
Vector opBinary(string op)(Vector l)if(op=="+"||op=="-"){//only addition and subtraction makes sense for 2D vectors
mixin("return Vector(x"~op~"l.x,y"~op~"l.y;");
}
///take in anything as long as a corresponding binaryOp exists
///this essentially rewrites all "vec op= variable;" to "vec = vec op variable;"
void opOpAssign(string op,T)(T l){
this = this.binaryOp!op(l);
}
Run Code Online (Sandbox Code Playgroud)
甚至其他缩放Vector
Vector opBinary(string op)(real l)if(op=="*"||op=="/"){
mixin("return Vector(x"~op~"l,y"~op~"l;");
}
Vector opBinaryRight(string op)(real l)if(op=="*"){// for 2 * vec
return this*l;
}
Run Code Online (Sandbox Code Playgroud)
注意,定义opBinary
小号限制哪些可以传给opOpAssign
但你可以去两种方式(定义opBinary
来讲opOpAssign
)