“There are no zero-cost abstractions” (https://www.youtube.com/watch?v=rHIkrotSwcc) is a good CppCon talk. It tells as to look for costs and benefits. For the C++ Core Guideline’s Month abstraction here are what I see as the costs and benefits. Your choice whether you feel the benefits outweigh the costs :
#include
// Guideline P1 is about expressing ideas directly in code. One part of that is
// about using user defined types that express an idea better than say an int.
// This file takes the Date/Month example in P1 and expands upon it.
// Neutral 1 : Despite wrapping the unsigned int it is no slower.
struct CalendarType
{
// Neutral 2 : The user does not know if the value is 0 based or 1 based.
unsigned int value;
// Cost 1 : Either the user has to use say month.value or we have to write boiler plate code for required methods.
// Mitigation 1 : C++ 20 boiler plate for comparison operators is a couple of one liners.
bool operator==(const CalendarType &other) const = default;
std::strong_ordering operator(const CalendarType &other) const = default;
};
// Cost 2 : We have a bit of boiler plate code to write.
// Mitigation 2 : We’ve put the common code into a base class.
struct Year : CalendarType
{
explicit Year(int year) : CalendarType(year) {}
};
struct Month : public CalendarType
{
explicit Month(int month) : CalendarType(month) {}
};
struct Day : public CalendarType
{
explicit Day(int day) : CalendarType(day) {}
};
class Date
{
public:
Date(Year year, Month month, Day day)
: m_year(year),
m_month(month),
m_day(day)
{
}
Year year() const
{
return m_year;
}
Month month() const
{
return m_month;
}
Day day() const
{
return m_day;
}
private:
// Cost 3 : To fully understand, the reader needs to look at how Year, Month and Day are implemented.
Year m_year;
Month m_month;
Day m_day;
};
int main()
{
// Cost 2 :
Date date1 {Year(1970), Month(4), Day(7)}; // Benefit 1 : It's clear to the reader what each argument is.
Date date2 {Year(1983), Month(1), Day(12)};
// Date date3 {7, 4, 1979}; // Benefit 2 : Code writer can't get them in the wrong order
// (courtesy of explicit this wont compile).
// (Yes, I've glossed over leap year edge cases)
bool earlierInTheYear = date2.month() < date1.month() ||
date2.month() == date1.month() && date2.day() < date1.day();
std::cout << "1983-01-12 " << (earlierInTheYear ? "is" : "is not")
<< " earlier in the year than 1970-04-07" << std::endl;
}
Comments URL: https://news.ycombinator.com/item?id=45898278
Points: 1
# Comments: 0
Source: news.ycombinator.com