Sự khác biệt giữa các kiểu / giá trị chrono C ++ 20 month{7}
và là months{7}
gì? Không khó hiểu khi có hai cái tên giống nhau như vậy phải không?
Sự khác biệt giữa các kiểu / giá trị chrono C ++ 20 month{7}
và là months{7}
gì? Không khó hiểu khi có hai cái tên giống nhau như vậy phải không?
Câu trả lời:
Có, có thể khó hiểu khi có cả hai month
và months
khi lần đầu tiên gặp thư viện này. Tuy nhiên, có những quy ước đặt tên nhất quán trong thư viện này để giúp giảm bớt sự nhầm lẫn đó. Và lợi ích là có sự phân tách rõ ràng các ngữ nghĩa riêng biệt trong khi vẫn giữ lại các tên ngắn gọn trực quan.
months
Tất cả các loại "được xác định trước" chrono::duration
là số nhiều:
nanoseconds
microseconds
milliseconds
seconds
minutes
hours
days
weeks
months
years
Đối với months
một chrono::duration
loại :
sử dụng tháng = thời lượng < kiểu số nguyên có dấu của ít nhất 20 bit , ratio_divide <years :: period, ratio <12> >>;
Và nó chính là 1 / 12 của years
.
static_assert(12*months{1} == years{1});
Bạn có thể in nó ra như sau:
cout << months{7} << '\n';
Và đầu ra là:
7[2629746]s
Đây là 7 đơn vị của 2,629,746 giây. Nó chỉ ra rằng 2,629,746 giây là độ dài trung bình của tháng trong lịch dân sự. Nói cách khác:
static_assert(months{1} == 2'629'746s);
(con số chính xác không đặc biệt quan trọng ngoại trừ cược thanh thắng)
month
month
(số ít) mặt khác không phải là a chrono::duration
. Nó là một công cụ chỉ định lịch cho một tháng trong năm trong lịch dân sự. Hoặc là:
static_assert(month{7} == July);
Điều này có thể được sử dụng để tạo thành một ngày như thế này:
auto independence_day = month{7}/4d/2020y;
Đại số của month
và months
phản ánh những ngữ nghĩa khác nhau này. Ví dụ: "Tháng 7 + Tháng 7" là vô nghĩa và do đó lỗi thời gian biên dịch:
auto x = month{7} + month{7};
~~~~~~~~ ^ ~~~~~~~~
error: invalid operands to binary expression ('std::chrono::month' and 'std::chrono::month')
Nhưng điều này hoàn toàn hợp lý:
auto constexpr x = month{7} + months{7};
static_assert(x == February);
Và điều này:
auto constexpr x = months{7} + months{7};
static_assert(x == months{14});
Chưa hết:
auto b = February == months{14};
~~~~~~~~ ^ ~~~~~~~~~~
error: invalid operands to binary expression ('const std::chrono::month' and 'std::chrono::months')
Tức là month
và months
không chỉ không bằng nhau, thậm chí chúng còn không thể so sánh được. Đó là táo và cam, nếu bạn thích loại trái cây. ;-)
Có một mối quan hệ tương tự giữa day
và days
. Và giữa year
và years
.
Nếu nó là số nhiều, nó là a
chrono::duration
.
Và chỉ <chrono>
có kiểu an toàn mới giúp bạn đảm bảo rằng hai khái niệm khác biệt về ngữ nghĩa và tương tự nhau này không bị nhầm lẫn với nhau trong mã của bạn.
12*x
tràn, bạn đã có hành vi không xác định ngay tại đó (trước khi phương thức months
khởi tạo chạy). Tuy nhiên, nếu giá trị của months
là bội số của 12 (dương hoặc âm), thì có, phép cộng (hoặc phép trừ) về cơ bản là không. Bạn sẽ nhận được điều tương tự như July == July + years(x)
.
July == July + months(12*x)
bất kể x không? Ngay cả đối với x là INT_MAX?