D中优雅的运算符重载 [英] Elegant operator overloading in D

查看:89
本文介绍了D中优雅的运算符重载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一阵子我对D的运算符重载的方向感到困惑,但是现在我意识到这是一个漂亮的系统……如果它仅适用于核心类型(int,float等).考虑以下代码:

For a while I was confused about the direction of D's operator overloading, but now I realize it's a beautiful system... if It would only work with core types (int, float, etc). Consider the follow code:

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):

This would be beautiful code if it worked, seeing as it overloads all +=, -=, *=, etc.. operators in one method. However, as you can see, it doesn't work out of the box. I have created a solution using templates (god I love 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);
    }
}

这很好,只有我更喜欢将所有内容都保留在内部".有没有办法在没有模板帮助的情况下完成这项工作?我知道我在这里很挑剔,因为没有性能损失,在需要这样做的情况下导入模块并不难.我只是想知道它是否是内置的,而我却忽略了某些东西.

This is fine, only I'd much prefer to keep everything "in house". Is there a way to make this work without the aid of a template? I know I'm being picky here, seeing as there's no performance loss and it's not hard to import a module in situation I need to do this. I'm just wondering if it's built in and I'm overlooking something.

推荐答案

D中几乎所有重载的运算符都是定义为的模板.注意,void opOpAssign(string op)(Vector vector)具有一个模板参数,该参数是一个字符串.因此,不,您不能将其作为非模板函数进行重载.现在,您不需要第二个模板(因此,如果问您是否需要一个模板,您是指一个助手模板,那么答案是否定的),但是重载的运算符功能已经是一个模板.

Almost all overloaded operators in D are templates by definition. Notice that void opOpAssign(string op)(Vector vector) has a template parameter which is a string. So, no you can't overload it as a non-template function. Now, you don't need a second template to do it (so if by asking whether you need a template, you mean a helper template, then the answer is no), but the overloaded operator function is already a template.

在这里做您想做的事情的规范方法是使用字符串混合器:

The canonical way to do what you you're trying to do here is to use string mixins:

void opOpAssign(string op)(Vector vector)
{
    mixin("X" ~ op ~ "=vector.X;");
    mixin("Y" ~ op ~ "=vector.Y;");
}

这篇关于D中优雅的运算符重载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆