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);
}