有一段时间我对 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
}
}
如果它有效的话,这将是一段漂亮的代码,因为它在一个方法中重载了所有 +=、-=、*= 等运算符。然而,正如您所看到的,它并不是开箱即用的。我已经使用模板创建了一个解决方案(上帝我爱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);
}
}
这很好,只是我更喜欢把所有东西都“放在家里”。有没有一种方法可以在不借助模板的情况下完成这项工作?我知道我在这里很挑剔,因为没有性能损失,而且在我需要这样做的情况下导入模块并不难。我只是想知道它是否是内置的,而我忽略了一些东西。
D 中几乎所有重载运算符都是模板根据定义。请注意void opOpAssign(string op)(Vector vector)
有一个模板参数,它是一个字符串。所以,不,你不能将它重载为非模板函数。现在,您不需要第二个模板来执行此操作(因此,如果通过询问您是否需要模板,您的意思是辅助模板,那么答案是否定的),但重载的运算符函数已经是一个模板。
执行此操作的规范方法是使用字符串混合:
void opOpAssign(string op)(Vector vector)
{
mixin("X" ~ op ~ "=vector.X;");
mixin("Y" ~ op ~ "=vector.Y;");
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)