It's harder to do than criticize.  Here's my attempt to implement a Celsius-to-Fahrenheit conversion table in C++.#include <cstdlib>#include <cstring>#include <iomanip>#include <iostream>#define DEGREE_SIGN \u00B0class Fahrenheit;class Celsius {  public:    explicit Celsius(double c) : c(c) {        if (c < MIN_VALUE) {            throw Temperature below minimum;        } else if (c > MAX_VALUE) {            throw Temperature above maximum;        }    }    Celsius(Fahrenheit f);    operator double() const { return c; }    Celsius operator +(Celsius incr) const { return Celsius(c + incr.c); }    Celsius &operator +=(Celsius incr) { c += incr.c; return *this; }    friend std::ostream &operator<<(std::ostream &os, Celsius c) {        return os << (double)c << DEGREE_SIGN << 'C';    }    static const Celsius MIN;  // Absolute zero    static const Celsius MAX;  // Absolute hot (approx.)  private:    double c;    static const double MIN_VALUE;    static const double MAX_VALUE;};class Fahrenheit {  public:    explicit Fahrenheit(double f) : f(f) {        if (f < MIN_VALUE) {            throw Temperature below minimum;        } else if (f > MAX_VALUE) {            throw Temperature above maximum;        }    }    Fahrenheit(Celsius c);    operator double() const { return f; }    Fahrenheit operator +(Fahrenheit incr) const { return Fahrenheit(f + incr.f); }    Fahrenheit &operator +=(Fahrenheit incr) { f += incr.f; return *this; }    friend std::ostream &operator<<(std::ostream &os, Fahrenheit f) {        return os << (double)f << DEGREE_SIGN << 'F';    }    static const Fahrenheit MIN;  // Absolute zero    static const Fahrenheit MAX;  // Absolute hot (approx.)  private:    double f;    static const double MIN_VALUE;    static const double MAX_VALUE;};Celsius::Celsius(Fahrenheit f) : c((f - 32) / 9 * 5) {}const double Celsius::MIN_VALUE = -273.15;const double Celsius::MAX_VALUE = 1.4e32;const Celsius Celsius::MIN = Celsius(Celsius::MIN_VALUE);const Celsius Celsius::MAX = Celsius(Celsius::MAX_VALUE);Fahrenheit::Fahrenheit(Celsius c) : f(c / 5 * 9 + 32) {}const double Fahrenheit::MIN_VALUE = -459.67;const double Fahrenheit::MAX_VALUE = 2.5e32;const Fahrenheit Fahrenheit::MIN = Fahrenheit(Fahrenheit::MIN_VALUE);const Fahrenheit Fahrenheit::MAX = Fahrenheit(Fahrenheit::MAX_VALUE);#ifdef _WIN32const char PATH_SEPARATOR = '\\';#elseconst char PATH_SEPARATOR = '/';#endifconst char *basename(const char *path) {    const char * sep = strrchr(path, PATH_SEPARATOR);    return sep ? sep + 1 : path;}int main(int argc, char *argv[]) {    if (argc != 4) {        std::cout << Usage:  << basename(argv[0]) <<  MIN MAX STEP << std:: endl;        return 1;    }    try {        char *minEnd, *maxEnd, *stepEnd;        Celsius min(strtod(argv[1], &minEnd)),                max(strtod(argv[2], &maxEnd)),                step(strtod(argv[3], &stepEnd));        if (*minEnd != '\0') {            std::cerr << Invalid minimum temperature << std::endl;            return 1;        } else if (*maxEnd != '\0') {            std::cerr << Invalid maximum temperature << std::endl;            return 1;        } else if (*stepEnd != '\0') {            std::cerr << Invalid temperature step << std::endl;            return 1;        }        if (step <= 0.0) {            std::cerr << Step must be positive << std::endl;            return 1;        } else if (step > max - min) {            std::cerr << Step exceeds temperature range << std::endl;            return 1;        } else if (max < min) {            std::cerr << Minimum temperature exceeds maximum temperature << std::endl;            return 1;        }        for (Celsius c = min; c <= max; c += step) {            std::cout << std::setw(8) << c                      << std::setw(8) << Fahrenheit(c)                      << std::endl;        }    } catch (const char *msg) {        std::cerr << msg << std::endl;        return 1;    }    return 0;}Some concerns I have:What do you think of the input validation?Is the code repetition justified?  Much of the Fahrenheit class is not strictly necessary for the problem, and is included for completeness.  Still, does the repetition enhance clarity, or is it harmful?
Celsius  Fahrenheit conversion table
c++;validation;floating point;unit conversion