D 中的优雅运算符重载

2023-12-19

有一段时间我对 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(使用前将#替换为@)

D 中的优雅运算符重载 的相关文章

  • C++ 友元函数模板重载和 SFINAE 在 clang++、g++、vc++ 中的不同行为(C++14 模式)

    因此 以下代码在 clang 3 8 0 下构建并成功运行 但在 g 6 3 0 和 vc 19 10 24903 0 下均失败 g 和 vc 都抱怨运算符 的重新定义 有谁知道这里哪个编译器有问题 对于无法编译代码的编译器 编译错误的解决
  • C++ Typedef 和运算符重载

    如果你定义一个类似的类型typedef int MY INT 并继续重载 MY INT 的加法运算符 例如 MY INT operator MY INT a MY INT b will MY INT a b a b 不同于 int A B
  • 可以重载花括号吗?

    我几乎可以肯定不是 但我没有找到明确的答案 是否可以重载花括号 如 class Foo int i public int operator int i return i 42 int main Foo f f 2 return 0 它从未被
  • 委托给私有部分

    有时 C 的隐私概念让我感到困惑 class Foo struct Bar Bar p public Bar operator gt const return p struct Foo Bar void baz std cout lt lt
  • 为什么 Python 有 __ne__ 运算符方法而不仅仅是 __eq__?

    答案here https stackoverflow com questions 4352244 python implementing ne operator based on eq给出您想要的案例的手动参考 ne 返回除逻辑倒数之外的其
  • C++“重载”if() 语句

    是否有可能改变if 以便 class Foo int x Foo foo if foo 仅当价值x是不是零的东西 或者 到 int 的显式用户定义类型转换是否有效 这是一种合适的方法吗 或者 最好做类似的事情if foo getX 您可以通
  • 类外的运算符重载[重复]

    这个问题在这里已经有答案了 有两种方法可以重载 C 类的运算符 课堂内 class Vector2 public float x y Vector2 operator const Vector2 other Vector2 ans ans
  • 尚不支持运算符重载?

    根据 Swift 编程指南 运算符重载是允许的 而且实际上非常通用 但是 我无法让它在操场上工作 例如 Equatable协议想要这样 func lhs Self rhs Self gt Bool 假设我做了一个简单的Location3D
  • 为什么 C# 运算符重载必须是静态的?

    为什么 C 要求运算符重载是静态方法而不是成员函数 如 C 也许更具体地说 这个决定的设计动机是什么 埃里克 利珀特 Eric Lippert 在一篇文章中对此进行了极其详细的回答 博客文章 https ericlippert com 20
  • C++ 模板复制构造函数,编译器说“传递 const 作为此参数丢弃限定符”

    我正在尝试创建动态矩阵的模板类 以我目前对 C 的了解 我设法解决了一些问题 但我陷入了复制构造函数和重载运算符 的困境 换句话说 我无法创建我的对象的副本 在我看来 这应该可行 但我的朋友编译器告诉我 我有 1 个错误 错误 将 cons
  • 全局运算符和成员运算符的区别

    定义一个接受类的两个引用的全局运算符和定义一个仅接受正确操作数的成员运算符之间有区别吗 Global class X public int value bool operator X left X right return left val
  • 重载“+”的不可变列表有意义吗?

    它当然没有脱离 NET框架的标准实践 当我看到一个a b我总是假设会有新的东西被创造出来 static void Main string args var list BuildList ImmutableList
  • 在 GTK+ (gtkD) 中处理按键

    我正在玩gtkD http www dsource org projects gtkd GTK 的 D 绑定 我有一个window对象 实例gtk MainWindow 我想处理它的按键 How 如何处理特殊键 例如箭头键 pgup pgd
  • 使用“,”运算符是否被认为是不好的形式?

    我创建了一个列表类 作为替换程序中用于初始化需要包含不断变化的元素列表的对象的可变参数函数的方法 列表类有一个我非常喜欢的使用语法 但是我以前没有见过它被使用过 所以我想知道我是否不应该因为这个事实而使用它 列表类的基本实现如下所示 inc
  • 不同类型的 C++ 对称二元运算符

    我正在学习 C 我想知道是否可以深入了解创建适用于两种不同类型实例的二元运算符的首选方法 这是我为了说明我的担忧而制作的一个例子 class A class B class A private int x public A int x in
  • D 并发写入缓冲区

    假设您有一个大小为 N 的缓冲区 必须将其设置为确定的值 例如零或其他值 缓冲区中的此值设置分为 M 个线程 每个线程处理缓冲区的 N M 个元素 缓冲区不能immutable 因为我们改变了值 消息传递也不起作用 因为禁止传递 ref 或
  • C++ 模板友元运算符重载

    我的代码有什么问题吗 template
  • 类模板上的运算符重载

    我在为模板类定义一些运算符重载时遇到一些问题 让我们以这个假设的类为例 template
  • GtkD(D语言的Gtk+绑定)为什么要编译它?

    我最近一直在使用 GtkD 和 D 编程语言来创建本机应用程序 我已经下载了所有必要的文件并运行了所有内容 因此我现在可以编译并生成示例应用程序 我的问题是 在一些指南中 它告诉您在您正在使用的平台上编译 GtkD 但这有什么意义呢 编译后
  • C++ 编译器必须选择两个转换运算符中的哪一个?

    一个类可以声明多个转换运算符 特别是 它可以是某种类型的转换运算符以及同一类型的常量引用 如果请求转换为该类型 则必须选择两个转换运算符中的哪一个 考虑一个例子 include

随机推荐