Sự khác biệt giữa chrono :: tháng và chrono :: tháng


105

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:


129

Có, có thể khó hiểu khi có cả hai monthmonthskhi 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::durationlà số nhiều:

  • nanoseconds
  • microseconds
  • milliseconds
  • seconds
  • minutes
  • hours
  • days
  • weeks
  • months
  • years

Đối với monthsmột chrono::durationloạ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 monthmonthsphả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à monthmonthskhô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 daydays. Và giữa yearyears.


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.


Nó có được đảm bảo là đúng July == July + months(12*x)bất kể x không? Ngay cả đối với x là INT_MAX?
PiotrNycz

3
Hầu hết. Nếu 12*xtràn, bạn đã có hành vi không xác định ngay tại đó (trước khi phương thức monthskhởi tạo chạy). Tuy nhiên, nếu giá trị của monthslà 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).
Howard Hinnant

Bạn đã hỏi câu hỏi của mình lúc 17:58 và bạn cũng trả lời câu hỏi đó lúc 17:58?
dejoma

2
Bạn không chỉ trả lời câu hỏi của riêng mình mà còn được khuyến khích rõ ràng: stackoverflow.blog/2011/07/01/… , stackoverflow.com/help/self-answer
Howard Hinnant
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.