Ich kenne nix fertiges -> sel-bär schreiben.
Wenn wir uns mal auf m, kg, s und A beschränken könnte das so aussehen:
template <int m_e, int kg_e, int s_e, int A_e> class si_unit
{
public:
si_unit(double v)
: m_value(v)
{
}
double get() const
{
return m_value;
}
void set(double v)
{
m_value = v;
}
private:
double m_value;
};
template <int m_e1, int kg_e1, int s_e1, int A_e1, int m_e2, int kg_e2, int s_e2, int A_e2>
si_unit<m_e1+m_e2, kg_e1+kg_e2, s_e1+s_e2, A_e1+A_e2> operator * (si_unit<m_e1, kg_e1, s_e1, A_e1> a, si_unit<m_e2, kg_e2, s_e2, A_e2> b)
{
return si_unit<m_e1+m_e2, kg_e1+kg_e2, s_e1+s_e2, A_e1+A_e2>(a.get() * b.get());
}
template <int m_e1, int kg_e1, int s_e1, int A_e1, int m_e2, int kg_e2, int s_e2, int A_e2>
si_unit<m_e1-m_e2, kg_e1-kg_e2, s_e1-s_e2, A_e1-A_e2> operator / (si_unit<m_e1, kg_e1, s_e1, A_e1> a, si_unit<m_e2, kg_e2, s_e2, A_e2> b)
{
return si_unit<m_e1-m_e2, kg_e1-kg_e2, s_e1-s_e2, A_e1-A_e2>(a.get() / b.get());
}
template <int m_e, int kg_e, int s_e, int A_e>
si_unit<m_e, kg_e, s_e, A_e> operator + (si_unit<m_e, kg_e, s_e, A_e> a, si_unit<m_e, kg_e, s_e, A_e> b)
{
return si_unit<m_e, kg_e, s_e, A_e>(a.get() + b.get());
}
template <int m_e, int kg_e, int s_e, int A_e>
si_unit<m_e, kg_e, s_e, A_e> operator - (si_unit<m_e, kg_e, s_e, A_e> a, si_unit<m_e, kg_e, s_e, A_e> b)
{
return si_unit<m_e, kg_e, s_e, A_e>(a.get() - b.get());
}
// könnte man wahrscheinlich statisch lösen, aber das tu' ich mir nicht an :)
template <int m_e, int kg_e, int s_e, int A_e> std::string get_name(si_unit<m_e, kg_e, s_e, A_e> const&)
{
std::stringstream strstr;
bool empty = true;
if (m_e != 0)
{
strstr << "m";
if (m_e != 1)
strstr << "^" << m_e;
empty = false;
}
if (kg_e != 0)
{
strstr << "kg";
if (kg_e != 1)
strstr << "^" << kg_e;
if (!empty)
strstr << " ";
empty = false;
}
if (s_e != 0)
{
strstr << "s";
if (s_e != 1)
strstr << "^" << s_e;
if (!empty)
strstr << " ";
empty = false;
}
if (A_e != 0)
{
strstr << "A";
if (A_e != 1)
strstr << "^" << A_e;
if (!empty)
strstr << " ";
empty = false;
}
if (empty)
return "1";
else
return strstr.str();
}
#define SI_TYPEDEF(m, kg, s, A, name, name2) \
typedef si_unit<m, kg, s, A> name; \
std::string get_name(name const&) \
{ \
return name2; \
}
SI_TYPEDEF( 1, 0, 0, 0, meters, "Meter")
SI_TYPEDEF( 0, 1, 0, 0, kilograms, "Kilogram")
SI_TYPEDEF( 0, 0, 1, 0, seconds, "Second")
SI_TYPEDEF( 0, 0, 0, 1, ampere, "Ampere")
SI_TYPEDEF( 0, 0, -1, 0, hertz, "Hertz")
SI_TYPEDEF( 1, 1, -2, 0, newtons, "Newton")
SI_TYPEDEF(-1, 1, -2, 0, pascal_, "Pascal")
SI_TYPEDEF( 2, 1, -2, 0, joule, "Joule")
SI_TYPEDEF( 2, 1, -3, 0, watts, "Watt")
SI_TYPEDEF( 0, 0, 1, 1, coulombs, "Coulomb")
SI_TYPEDEF( 2, 1, -3, -1, volts, "Volt")
SI_TYPEDEF(-2, -1, 4, 2, farads, "Farad")
SI_TYPEDEF( 2, 1, -3, -2, ohms, "Ohm")
SI_TYPEDEF(-2, -1, 3, 2, siemens, "Siemens")
SI_TYPEDEF( 2, 1, -2, -1, webers, "Weber")
SI_TYPEDEF( 0, 1, -2, -1, teslas, "Tesla")
SI_TYPEDEF( 2, 1, -2, -2, henrys, "Henry")
SI_TYPEDEF( 2, 0, 0, 0, square_meters, "Meter^2")
//...
int main()
{
volts U(10);
ampere I(2);
ohms R = U/I; // geht
// ohms R2 = volts(1) * volts(1); // geht nicht
watts P = ampere(10) * volts(20); // geht auch
joule W = P * seconds(60); // und das auch
square_meters A = meters(10) * meters(100);
}
Wenns dir Spass macht kannst du es ja noch um Kelvin, Mole und Candela erweitern
Nachdem das aber kaum ein grosser Aufwand ist wie man sieht, gehe ich fast davon aus dass es sowas (nur wahrscheinlich wesentlich vollständiger) schon irgendwo gibt. Jetzt muss es nurnoch wer finden