Mẫu lồng nhau
Các mẫu có thể được lồng trong các lớp/cấu trúc hoặc trong các mẫu lớp/cấu trúc khác. Điều này cũng đúng với các liên minh.
Trong phần Unions, chúng ta đã thấy khả năng "chuyển đổi" các giá trị long
thành double
và ngược lại mà không mất độ chính xác.
Bây giờ chúng ta có thể sử dụng mẫu để viết một "bộ chuyển đổi" phổ quát (TemplatesConverter.mq5
). Lớp mẫu Converter
có hai tham số T1 và T2, biểu thị các kiểu mà việc chuyển đổi sẽ được thực hiện giữa chúng. Để ghi một giá trị theo quy tắc của một kiểu và đọc theo quy tắc của kiểu khác, chúng ta lại cần một liên minh. Chúng ta cũng sẽ biến nó thành một mẫu (DataOverlay
) với các tham số U1 và U2, và định nghĩa nó bên trong lớp.
Lớp này cung cấp một sự chuyển đổi tiện lợi bằng cách nạp chồng các toán tử []
, trong đó các trường của liên minh được ghi và đọc.
template<typename T1,typename T2>
class Converter
{
private:
template<typename U1,typename U2>
union DataOverlay
{
U1 L;
U2 D;
};
DataOverlay<T1,T2> data;
public:
T2 operator[](const T1 L)
{
data.L = L;
return data.D;
}
T1 operator[](const T2 D)
{
data.D = D;
return data.L;
}
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Liên minh được sử dụng để mô tả trường DataOverlay<T1,T2> data
bên trong lớp. Chúng ta có thể sử dụng trực tiếp T1 và T2 trong DataOverlay
và không biến liên minh này thành mẫu. Nhưng để thể hiện kỹ thuật này, các tham số của mẫu bên ngoài được truyền vào mẫu bên trong khi trường data
được tạo. Bên trong DataOverlay
, cặp kiểu tương tự sẽ được biết đến dưới dạng U1 và U2 (bên cạnh T1 và T2).
Hãy xem mẫu này hoạt động như thế nào.
#define MAX_LONG_IN_DOUBLE 9007199254740992
void OnStart()
{
Converter<double,ulong> c;
const ulong value = MAX_LONG_IN_DOUBLE + 1;
double d = value; // có thể mất dữ liệu do chuyển đổi kiểu
ulong result = d; // có thể mất dữ liệu do chuyển đổi kiểu
Print(value == result); // false
double z = c[value];
ulong restored = c[z];
Print(value == restored); // true
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18