Does C++ offer something similar to Ada's subtype
to narrow a type?
E.g.:
type Weekday is (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday);
subtype Working_Day is Weekday range Monday .. Friday;
Does C++ offer something similar to Ada's subtype
to narrow a type?
E.g.:
type Weekday is (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday);
subtype Working_Day is Weekday range Monday .. Friday;
Range checking has a cost. C++ has a zero cost policy for features: if you want the feature and you should pay a cost for it, you need to be explicit. That being said, mostly you can use some library or write your own.
Also, what do you expect when someone tries to put
Sunday
toWorking_Day
? An exception (most likely)? To set it toMonday
? To set it toFriday
? Invalidate the object? Keep the same value and ignore that (bad idea)?As an example:
which outputs:
There are a few additional differences between C++ enumerations and Ada enumerations. The following Ada code demonstrates some of these differences.
The output of this program is:
The subtype Work_Days has an is-a relationship with the type Days. Every member of Work_Days is also a member of Days. In this example the set of valid values for Work_Days is a subset of the set of valid values for Days.
Characters in Ada are defined as an enumeration. It is therefore simple to define subtypes of the type Character for special uses. The following example reads text from a file and counts the number of occurrences of upper case letters and lower case letters, ignoring all other characters in the file.
Two subtypes of Character are defined. The subtype Upper_Case contains the range of Character values from 'A' through 'Z', while the subtype Lower_Case contains the range of Character values from 'a' through 'z'.
Two arrays are created for counting the letters read. The array Uppers is indexed by the set of Upper_Case values. Each element of the array is an instance of Natural, which is a pre-defined subtype of Integer containing only non-negative values. The array Lowers is indexed by the set of Lower_Case values. Each element of Lowers is also an instance of Natural.
The program prompts for a file name, opens that file, then reads the file one line at a time. The characters in each line are parsed. If the character is an Upper_Case character the array element in Uppers indexed by the parsed letter is incremented. If the character is a Lower_Case character the array element in Lowers indexed by the parsed letter is incremented.
The following output is the result of reading the source file for the count_letters program.
No, not natively.
What you describe might be best represented as a scoped enum, accompanied by a separate scoped enum with a subset of enumerations who share numerical representations with the "parent" scoped enum.
You could further define some conversions between the two, but without reflection it's not really possible to make it all elegant and intuitive, at least not without hardcoding and duplicating loads of stuff which rather defeats the purpose.
It would be best, when programming C++, to attempt entirely abandoning the mindset imbued by programming in other languages.
That being said, this is actually quite a nice feature idea, though I wouldn't hold my breath!
Workaround: just use an enum, and apply range checking where you need to.
Probably you can overload the assignation with a postcondition
Purely theoretical. Have not tried myself. But what do you guys think?
But is funny to appreciate how every upgrade on C++ they push as advanced features all the stuff Ada programmers take for granted.
What you want might (at least partially) be realized using
std::variant
introduced with C++17.The following code defines
sub_variant_t
which constructs a newvariant
from the submitted type. E.g.using Working_Day= sub_variant_t<WeekDay,5>;
takes the first five elements fromWeekday
.If you want to copy values from the smaller type (
Working_Day
) to the larger one (Weekday
) you can useWeekDay d3= var2var<WeekDay>( d1 );
wherevar2var
is defined as follows.See this livedemo.