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);
Here's what I came up with... pretty much the same idea as Anders K, but since I wrote the code, I'll post it:
#include <iostream>
using namespace std;
class MilliVoltsValue;
class VoltsValue;
class VoltsValue
{
public:
explicit VoltsValue(float v = 0.0f) : _volts(v) {/* empty */}
VoltsValue(const MilliVoltsValue & mV);
operator float() const {return _volts;}
private:
float _volts;
};
class MilliVoltsValue
{
public:
explicit MilliVoltsValue(float mV = 0.0f) : _milliVolts(mV) {/* empty */}
MilliVoltsValue(const VoltsValue & v) : _milliVolts(v*1000.0f) {/* empty */}
operator float() const {return _milliVolts;}
private:
float _milliVolts;
};
VoltsValue :: VoltsValue(const MilliVoltsValue & mV) : _volts(mV/1000.0f) {/* empty */}
class PowerMeter
{
public:
PowerMeter() {/* empty */}
void forceVoltage(const VoltsValue & v) {_voltsValue = v;}
VoltsValue getVoltage() const {return _voltsValue;}
private:
VoltsValue _voltsValue;
};
int main(int argc, char ** argv)
{
PowerMeter meter;
meter.forceVoltage(VoltsValue(5.0f));
cout << "Current PowerMeter voltage is " << meter.getVoltage() << " volts!" << endl;
meter.forceVoltage(MilliVoltsValue(2500.0f));
cout << "Now PowerMeter voltage is " << meter.getVoltage() << " volts!" << endl;
// The line below will give a compile error, because units aren't specified
meter.forceVoltage(3.0f); // error!
return 0;
}
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.