| Mauro 的个人资料Taming the Jungle照片日志列表 | 帮助 |
|
4月17日 Automatic checking numeric rangeI was recently involved in a discussion about the lack of “ranged ints” in the C# language. A ranged int is an integer type that would only accept a smaller subrange of all possible integers, say just 1 to 100. This is a discussion dear to me be because I sort of designed “ranged ints” for C++.
It all started because I used to develop with Turbo Pascal which *had* “ranged” integer types. You could turn on a compiler option that would automatically validate the range at runtime. I used it as a debugging aid, like an “automatic assert” every time the variable was assigned to. For instance, I would have a “row” variable that must hold values between 1 and 24, so I would declare it to be of a “row type”, a ranged integer of 1 to 24. During development and testing I would get an error if it got assigned something outside of that range. The final “non-checked” version would have this option turned off and have no performance penalties.
Then I had to switch to C++ and I missed my “ranged ints”. Since C++ templates allowed not only types but constants as arguments as well, I developed my own “ranged int” classes based on templates. At debug time they would check the range. I then flipped a compiler “define” and they would behave pretty much like a normal int, semantically and performance wise. This was not a popular C++ technique, but I used it left and right, despite that it made for slower compilations and at one point the Borland C++ compiler would choke with so much template usage.
I dusted off my C++ skills and wrote such an example as a console Win32 app below – this one is pretty simple (no copy constructor, no necessary operator overloading) and it will actually coerce the value to be within the range instead of issuing a warning, but you can get the idea. Of course, you could do the same with other numeric types such as float.
I couldn’t replicate the technique with C#. Maybe if it would accept constants as generics arguments, I could have my “ranged ints” back…
Here is the sample:
#include "stdafx.h"
#define DEBUG template <int V1, int V2> class RangeInt { private: int Value; #ifdef DEBUG // Checks range and force into the range if outside // An alternative would be to throw an exception or flag the error somehow void CheckRange() { if (Value < V1) { Value = V1; } if (Value > V2) { Value = V2; } } #endif public: RangeInt() { Value = V1; } RangeInt(int N) { Value = N; #ifdef DEBUG CheckRange(); #endif } operator int() { return Value; } }; int _tmain(int argc, _TCHAR* argv[])
{ RangeInt<1, 100> MyVal; MyVal = 0; printf("%d\n", MyVal); MyVal = 1000; printf("%d\n", MyVal); return 0; } 评论 (4)
引用通告此日志的引用通告 URL 是: http://maurosjungle.spaces.live.com/blog/cns!F3CEB0849B03B6CC!651.trak 引用此项的网络日志
|
|
|