我使用 Stroustrup 在GoingNative 2012(从 23:00 分钟开始)提出的用户定义文字来玩单元实现。这是代码:
#include <iostream>
using std::cout;
using std::endl;
template<int M, int K, int S>
struct Unit { // a unit in the MKS system
enum {m=M,kg=K,s=S};
};
template<typename Unit> // a magnitude with a unit
struct Value {
double val;
constexpr Value(double d) : val(d) {}
};
using Meter = Unit<1,0,0>;
using Second = Unit<0,0,1>;
using Distance = Value< Meter >;
using Time = Value< Second >;
using Velocity = Value< Unit<1,0,-1> >;
constexpr Value<Meter> operator "" _m(long double d)
// a f-p literal with suffix 'm'
{
return Distance(d);
}
constexpr Value<Second> operator"" _s(long double d)
// a f-p literal with suffix 's'
{
return Time(d);
}
constexpr Velocity operator/(Distance d, Time t)
{
return ( d.val / t.val );
}
int main(void)
{
Distance s = 100._m;
Time t = 22._s;
Velocity v = s/t;
cout << "s " << s.val << "\nt " << t.val << endl;
cout << "v " << v.val << endl;
return 0;
}
正如你所看到的,我自由地定义了一个operator/
来计算速度。输出是(需要gcc-4.7):
$ g++ -std=c++0x test_units_02.cc && ./a.out
s 100
t 22
v 4.54545
到现在为止还挺好。现在我想将一个包含单位表示的字符串添加到结构单元(或值?)。无论我想怎样写
cout << "v " << v.val << v.unit << endl;
并得到类似的东西
v 4.54545 m^1 s^-1
或者
v 4.54545 m^1 kg^0 s^-1
它不需要很漂亮,因为它只是为了检查。并学习如何去做;)。
当然,优雅的解决方案是在编译时评估所有内容。
我对此进行了一些尝试,但我不会用我没有结果的尝试让您感到厌烦/混淆...