I'm writing a simple class to setup a serial port on an AVR microcontroller. There are some parameters that have only a few meaningful values, for example baud rate, parity type or the number of stop bits. So, I'd like to create a type, a subset of integers, that can either be 1 or 2. I could make an enum type:
enum stopBits { one, two };
I do not like this solution (spelling out baud rate values?). I have come up with this instead:
template<int vv> struct stopBits {
static_assert( vv == 1 || vv == 2, "stop bit values can be 1 or 2");
int value = vv;
};
// usage:
stopBits<2> s;
I like this a lot more, and I like having a useful error message from compiler output. I would prefer to be able to instead initialize s with a copy constructor:
// I'd like to have this
stopBits s = 2;
This way, I'd be able to write a class with something like:
serial::serial(baudRate b, stopBits s = 1, parity p = none);
Searching for solutions, I found myself going down a rabbit hole: template parameters deduction, bounded::integer library, function parameters that can not be constexpr, this and this. Can this be done or it is best to surrender and move on? Thanks in advance to everyone.
You can either have run-time or compile-time checks, but not both.
If you have compile-time checks you are forced to somehow hard code the values. This is the domain of constexpr and static_assert. This is somewhat your first solution.
If you want to pass the value into a constructor you are loosing compile time validation, since you are now assigning values and the compiler does not know what value may be passed to the constructor. You can use things like bounded::integer or roll your own that check the value at run-time and behaves accordingly. (e.g. runtime_error)
The question you need to ask yourself what is an immutable property of the code. If it is immutable (for this use case) you should use template arguments. If it is immutable for this instance, but may vary within a use case, you should use a constant member variable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With