https://rentry.org/PPP2_p325

// Code derived from Stroustrup's PPP2 book
// § 9.7.1 Argument types
//  -and beginning on p 325

#include <iostream>

using namespace std;

// year in [min:max) range
class Year {
  static const int min = 1800;
  static const int max = 2200;

 public:
  Year(int x) : y{x}
  {
    if (x < min || max <= x)
      throw Invalid{};
  }

  class Invalid {};

  int year() { return y; }

 private:
  int y;
};

enum class Month {
  jan = 1,
  feb,
  mar,
  apr,
  may,
  jun,
  jul,
  aug,
  sep,
  oct,
  nov,
  dec
};

class Date {
 public:
  Date(Year y, Month m, int d);

  // . . .

  Year  year() { return y; }
  Month month() { return m; }
  int   day() { return d; }

 private:
  Year  y;
  Month m;
  int   d;  // day
};

Date::Date(Year yy, Month mm, int dd) : y{yy}, m{mm}, d{dd} {}

int main()
try {
  // Date dx1{Year{1998}, 4, 3};            // error: 2nd argument not a Month
  // Date dx2{Year{1998}, 4, Month::mar};   // error: 2nd argument not a Month
  // Date dx2{4, Month::mar, Year{1998}};   // error: 1st argument not a Year
  // Date dx2{Month::mar, 4, Year{1998}};   // error: 2nd argument not a Month
  Date dx3{Year{1998}, Month::mar, 30};  // OK

  // This unlikely error would still not be caught until run-time:
  Date dx2{Year{4}, Month::mar, 1998};  // run-time error: Year::Invalid

} catch (Year::Invalid&) {
  cerr << "error: Invalid year\n";
  return 1;

} catch (...) {
  cerr << "Oops: unknown exception!\n";
  return 2;
}

build & run:

g++ -std=c++20 -O2 -Wall -pedantic ./ch_09/main_p325.cpp && ./a.out

PrevUpNext

Edit
Pub: 06 Apr 2023 17:41 UTC
Edit: 03 May 2023 01:16 UTC
Views: 330