Reputation: 1175
i need to work with "indicator" variables I
that may take on one of 3 integer values {-1, 0, 1}.
so i would rather not declare
int I;
but rather
indicator_t I;
where the type indicator_t
~ {-1, 0, 1}
if furthermore i can later use I
in numerical expressions, as an integer (without casting?), that would be excellent.
question:
how should i define the type indicator_t
?
Upvotes: 2
Views: 101
Reputation: 11220
The simplest approach would be to convert the tri-state input into an enum class
with 3 fixed discriminators:
enum class indicator_t {
negative = -1,
zero = 0,
positive = 1,
};
There are several nice things with this approach:
enum class
makes it a unique type from int
s, which allow both the enum and an integer to appear as part of an overload set, if neededenum
logically has a cardinality of 3 (the type can accept 3 logical inputs). 1
a != 2
2 even though 2
is never a possible inputindicator_t
, it's clear from the call-site the intention. Consider the difference between the following two code snippets:
accept(1); // is this an indicator?
accept(indicator_t::positive); // ah, it's an indicator
If you need to convert to / from numeric values, you can create simple wrappers for this as well:
auto to_int(indicator_t indicator) -> int
{
return static_cast<int>(indicator);
}
auto to_indicator(int indicator) -> indicator_t
{
if (indicator > 1 || indicator < -1) {
// handle error. Throw an exception?
}
return static_cast<indicator_t>(indicator);
}
1 Technically C++ enums can take on any integral value that fits in std::underlying_type_t<the_enum>
, but this doesn't change that the logical valid set of inputs is fixed, which prevents developer bugs. Compilers will even try to warn on checks outside of the logical range.
2 Technically this could still be done, but you'd need to explicitly static_cast
all the time -- so it would appear as a code smell rather than a silently missed logic bug.
Upvotes: 5