D语言中的重载操作
数组操作符重载
数组索引操作符 opIndex
数组索引操作符,a[b1, b2, ... bn],可以通过声明一个名叫 opIndex 的函数来实现重载,该函数带有一个或更多参数。
分割操作符重载 opSlice
重载分割操作符意味着重载像 a[] 和 a[i..j] 那样的表达式。这个可通过声明一个名叫 opSlice 的成员函数来实现。
索引赋值操作符重载 opIndexAssign
如果一个赋值的左边是一个关于结构或类实例的索引操作,那么它可以通过提供一个opIndexAssign成员函数来重载。形如 a[b1, b2, ... bn] = c 的表达式可以被改写为a.opIndexAssign(c, b1, b2, ... bn)。
分割赋值操作符重载 opSliceAssign
如果一个赋值的左边是一个关于结构或类实例的分割操作,那么它可以通过提供一个opSliceAssign 成员函数来重载。形如 a[i..j] = c 的表达式可以被改写为a.opSliceAssign(c, i, j), and a[] = c as a.opSliceAssign(c)。
赋值操作符重载
以下操作符可以被重载:
| += | -= | *= | /= | %= | ^^= | &= |
|---|---|---|---|---|---|---|
| |= | ^= | <<= | >>= | >>>= | ~= |
表达式: a op= b
数组索引操作符重载 opIndexOpAssign
如果一个 op= 的左边是一个关于结构或类实例的索引表达式,并且 opIndexOpAssign 也是
成员:a[b1, b2, ... bn] op= c 则它可以改写成这样:a.opIndexOpAssign!("op")(c, b1, b2, ... bn).
分割赋值操作符重载 opSliceOpAssign
如果一个 op= 的左边是一个关于结构或类实例的分割表达式,并且 opSliceOpAssign 也是成
员:a[i..j] op= c 则它可以改写成这样:a.opSliceOpAssign!("op")(c, i, j)
技巧
- 注:同时存在
opIndexAssign和opSliceAssign的函数定义,无游标索引赋值优先使用opIndexAssign.
范例代码
struct A{
int opIndex();
int opIndex(size_t i); // auto v1 = (A)[i];
int opIndex(T...)(size_t i,T indices); // 模板方式
int opIndexAssign(int v); //
int opIndexAssign(int v,size_t i); //
int opIndexAssign(T...)(int v,size_t i0,T indices); // 模板方式
int[2] opSlice(size_t x,size_t y);
int opSliceAssign(int v);
int opSliceAssign(int v,size_t x,size_t y);
int opIndexOpAssign(string op)(int v);
int opSliceOpAssign(string op)(int v,size_t x,size_t y);
}
void test()
{
A a;
int i0,i1,i2,i3;
i0 = a[]; // 等同于 a.opIndex();
i1 = a[1]; // 等同于 a.opIndex(1);
i2 = a[1,2,3,4,5]; // 等同于 a.opIndex(1,2,3,4,5);
a[] = 5; // 同时存在 opIndexAssign(int v) 和 opSliceAssign(int v) 优先调用 a.opIndexAssign(5);
a[1] = 5; // 等同于 a.opIndexAssign(5,1);
a[1,2,3] = 5; // 等同于 a.opIndexAssign(5,1,2,3);
i3 = a[1..3]; // 等同于 a.opSlice(1,3);
a[1..3] = 5; // 等同于 a.opSliceAssign(5,1,3);
}
347





