Некоторое время я был озадачен направлением перегрузки операторов 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);
}
}
Это хорошо, только я бы предпочел, чтобы все было "в доме". Есть ли способ сделать эту работу без помощи шаблона? Я знаю, что я привередлив, потому что нет потери производительности и нетрудно импортировать модуль в ситуации, когда мне нужно это сделать. Мне просто интересно, встроен ли он, и я что-то пропускаю.