Am 20.02.18 um 14:58 schrieb Chris Angelico:
Okay. Now create a constraint on a name in C++ such that it can only
accept integers representing A.D. years which, on the Gregorian
calendar, are leap years. (Using a dedicated integer-like type is
permitted.) It must accept all multiples of four, except those which
are multiples of one hundred, unless they're also multiples of four
hundred.
That's what Steve asked for. Can you do it? Or is the C++ type system
not flexible enough for that?
It might be possible to do that with compile-time checking for
compile-time constants. For runtime checking, you already got the answer
- provide a
class LeapYear {
LeapYear(int y) {
if (!condition....) throw std::runtime_eror();
}
operator = (int y) { ...also test and throw... }
};
then:
LeapYear y2000 = 2000; // works
y2000 = 2004; // works
y2000 = 2001; // throws an error
The difference to Python is that "a=b" and "a+=b" are similar in C++, in
both cases you call a method on the object "a", whereas in Python the
first one is handled independently of the type of "a".
If you insist in compile-time checking, I think it's possible, though
I'm not one of those C++ wizards to implement it from up my sleeve. The
basic technique will be that you make your LeapYear
constructible/assignable from a static type only where constructino of
the type fails if the condition is not met. So
class LeapYear {
...
template<int n> operator = (LeapYearCheck<n> y)
{
// at this point, we are sure that LeapYearCheck succeeded
}
};
LeapYearCheck<n> could be implemented using template metaprogramming
(quite horrible) or the new funky constexpr feature in C++11/C++14 (less
horrible).
However this will throw an error whenever the compiler can't prove that
the year is a leap year, effectively only when it can be computed at
compile time, which certainly limits the usefulness of this type.
--
https://mail.python.org/mailman/listinfo/python-list