อะไรคือความแตกต่างระหว่าง chrono :: month และ chrono :: months


106

อะไรคือความแตกต่างระหว่างประเภท / ค่าโครโน C ++ 20 month{7}และmonths{7}อะไร? ไม่สับสนที่จะมีชื่อคล้ายกันสองชื่อ?

คำตอบ:


130

ใช่อาจสร้างความสับสนให้กับทั้งสองmonthและmonthsเมื่อพบห้องสมุดนี้เป็นครั้งแรก อย่างไรก็ตามมีหลักการตั้งชื่อที่สอดคล้องกันในไลบรารีนี้เพื่อช่วยลดความสับสน และข้อดีคือมีการแยกความหมายที่แตกต่างกันอย่างชัดเจนในขณะที่ยังคงรักษาชื่อที่ใช้งานง่าย

months

chrono::durationประเภทที่"กำหนดไว้ล่วงหน้า" ทั้งหมดเป็นพหูพจน์:

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

ดังนั้นmonthsเป็นchrono::durationประเภท :

โดยใช้ระยะเวลาเดือน = < ลงนามชนิดจำนวนเต็มอย่างน้อย 20 บิต ,
                         Ratio_divide <ปี :: ระยะเวลาอัตราส่วน <12> >>;

และมันก็เป็นสิ่งที่1 / 12yearsของ

static_assert(12*months{1} == years{1});

คุณสามารถพิมพ์ออกมาได้ดังนี้:

cout << months{7} << '\n';

และผลลัพธ์คือ:

7[2629746]s

สิ่งนี้อ่านเป็น 7 หน่วยจาก 2,629,746 วินาที ปรากฎว่า 2,629,746 วินาทีคือความยาวเฉลี่ยของเดือนในปฏิทินพลเรือน ระบุแตกต่างกัน:

static_assert(months{1} == 2'629'746s);

(จำนวนที่แน่นอนไม่สำคัญอย่างยิ่งยกเว้นการชนะเดิมพันบาร์)

month

month(เอกพจน์) ในทางกลับกันไม่ใช่chrono::duration. เป็นตัวระบุปฏิทินสำหรับเดือนของปีในปฏิทินพลเรือน หรือ:

static_assert(month{7} == July);

สามารถใช้เพื่อสร้างวันที่ดังนี้:

auto independence_day = month{7}/4d/2020y;

พีชคณิตของmonthและmonthsสะท้อนถึงความหมายที่แตกต่างกันเหล่านี้ ตัวอย่างเช่น "กรกฎาคม + กรกฎาคม" เป็นเรื่องไร้สาระและทำให้เกิดข้อผิดพลาดเวลาคอมไพล์:

auto x = month{7} + month{7};
         ~~~~~~~~ ^ ~~~~~~~~
error: invalid operands to binary expression ('std::chrono::month' and 'std::chrono::month')

แต่สิ่งนี้สมเหตุสมผล:

auto constexpr x = month{7} + months{7};
static_assert(x == February);

และนี่:

auto constexpr x = months{7} + months{7};
static_assert(x == months{14});

และยัง:

auto b = February == months{14};
         ~~~~~~~~ ^  ~~~~~~~~~~
error: invalid operands to binary expression ('const std::chrono::month' and 'std::chrono::months')

กล่าวคือmonthและmonthsไม่เพียง แต่ไม่เท่ากัน แต่ยังเทียบไม่ได้ด้วยซ้ำ พวกเขาคือแอปเปิ้ลและส้มหากคุณชอบผลไม้ ;-)

มีความสัมพันธ์ที่คล้ายกันระหว่างเป็นและday daysและระหว่างyearและyears.


ถ้าเป็นพหูพจน์ก็คือกchrono::duration.


และ<chrono>มีเพียงประเภทความปลอดภัยเท่านั้นที่จะช่วยให้คุณมั่นใจได้ว่าแนวคิดทั้งสองนี้แตกต่างกันทางความหมายและยังคล้ายคลึงกันจะไม่สับสนระหว่างกันในโค้ดของคุณ


รับประกันว่าจะเป็นจริง July == July + months(12*x)โดยไม่คำนึงถึง x? แม้ x จะเป็น INT_MAX?
PiotrNycz

3
เกือบ. หาก12*xมีmonthsมากเกินไปแสดงว่าคุณมีพฤติกรรมที่ไม่ได้กำหนดไว้ที่นั่น (ก่อนที่ตัวสร้างจะทำงาน) อย่างไรก็ตามหากค่าของmonthsเป็นผลคูณของ 12 (บวกหรือลบ) แสดงว่าการบวก (หรือการลบ) นั้นเป็นสิ่งที่ไม่ต้องทำ คุณจะได้รับสิ่งเดียวกับJuly == July + years(x).
Howard Hinnant

คุณถามคำถามของคุณ 17:58 และคุณตอบเมื่อ 17:58 ด้วย?
dejoma

2
ไม่เพียง แต่ตอบคำถามของคุณเองเท่านั้น แต่ขอแนะนำอย่างชัดเจน: stackoverflow.blog/2011/07/01/… , stackoverflow.com/help/self-answer
Howard Hinnant
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.