I am currently designing an API where I want that the user to be able to write code like this:
PowerMeter.forceVoltage(1 mV);
PowerMeter.settlingTime(1 ms);
Currently we do this using defines like:
#define mV *1.0e-03
This makes it very convenient for the user to write their code and it is also very readable, but of course has also drawbacks:
int ms;
Will throw some compiler errors which are hard to understand. So I am looking for a better solution.
I tried the new C++11 literals, but with this all I could achieve is:
long double operator "" _mV(long double value) {
return value * 1e-3;
}
PowerMeter.forceVoltage(1_mV);
In the end the API does not care about the unit like Volt or second but only takes the number, so I don't want to do any checking if you really input Volts in forceVoltage or not. So this should also be possible:
PowerMeter.forceVoltage(2 ms);
Any idea besides staying with the defines?
how about instead turning it around a bit by creating classes (ms,mV) for the different currents
e.g.
PowerMeter.forceVoltage( mV(1) );
PowerMeter.settlingTime( ms(1) )
It is pretty clear to the user and arguably not hard to read plus you would get type checking for free. having a common base class for the different units would make it easier to implement.
You can see the library "C++ Units" from Calum Grant as a good example of how to implement this. The library is a bit outdated, but still worth to see or may be to use.
Also, i think it might be interesting to read: "Applied Template Metaprogramming in SI UNITS: the Library of Unit-Based Computation"
There is one more good library: UDUNITS-2 which:
contains a C library for units of physical quantities and a unit-definition and value-conversion utility.
You could use C++11's compile-time rational arithmetic support for the units, instead of defining literals or macros for the units.
Take a look at Boost.Units. Here's some example code:
quantity<energy>
work(const quantity<force>& F, const quantity<length>& dx)
{
return F * dx; // Defines the relation: work = force * distance.
}
...
/// Test calculation of work.
quantity<force> F(2.0 * newton); // Define a quantity of force.
quantity<length> dx(2.0 * meter); // and a distance,
quantity<energy> E(work(F,dx)); // and calculate the work done.
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