在C ++中input安全的物理操作
它是否使C ++中的sens将物理单元定义为单独的types并定义这些types之间的有效操作?
引入大量的types和大量的运算符重载,而不是仅仅使用普通的浮点值来表示它们是否有优势?
例:
class Time{...}; class Length{...}; class Speed{...}; ... Time operator""_s(long double val){...} Length operator""_m(long double val){...} ... Speed operator/(const Length&, const Time&){...}
Time
, Length
和Speed
只能作为来自不同运营商的回报types创build?
它是否使C ++中的sens将物理单元定义为单独的types,并定义这些types之间的有效操作?
绝对。 标准Chrono图书馆已经为时间点和持续时间做了这个。
引入大量的types和大量的运算符重载,而不是仅仅使用普通的浮点值来表示它们是否有优势?
是的:您可以使用types系统来捕捉错误,比如在编译时向一个距离添加质量,而不会增加任何运行时间的开销。
如果你不想自己定义types和操作符,Boost有一个单元库 。
我真的会推荐boost :: units 。 它做所有的转换编译时,也给你一个编译时错误,如果你尝试使用错误的尺寸psuedo代码示例:
length l1, l2, l3; area a1 = l1 * l2; // Compiles area a2 = l1 * l2 * l3; // Compile time error, an area can't be the product of three lengths. volume v1 = l1 * l2 * l3; // Compiles
我走了这条路 types安全的优点是所有正常的众多和好的优点。 我遇到的缺点:
- 您需要在计算中保存中间值…例如秒平方。 具有这些值是一种types是没有意义的(秒^ 2显然不是像
velocity
types)。 - 你会想做越来越复杂的计算,这将需要越来越多的重载/运算符定义来实现。
在一天结束时,它对于简单的计算和简单的目的来说是非常干净的。 但是,当math变得复杂时,很难有一个打字单位系统打好。
每个人都提到了types安全保证。 另一个巨大的优势是能够从单位(米)中抽象出概念(长度)。
例如,处理单位时常见的问题是将SI与度量混合。 当概念被抽象为类时,这不再是一个问题:
Length width = Length::fromMeters(2.0); Length height = Length::fromFeet(6.5); Area area = width * height; //Area is computed correctly! cout << "The total area is " << area.toInches() << " inches squared.";
这个类的用户不需要知道什么单位的内部表示使用…至less,只要没有严重的舍入问题。
我真的希望更多的三angular函数库做到这一点,因为我总是要查看他们是否期望度数或弧度。
对于那些寻找一个function强大的编译时types安全的单元库,但对拖拽boost依赖犹豫不决,检查单位 。 这个库是作为一个单独的.h文件实现的,没有依赖关系,并附带了一个构buildunit testing/文档的项目。 它使用msvc2013,2015和gcc-4.9.2进行了testing,并且应该可以与这些编译器的更高版本一起使用。
完全披露:我是图书馆的作者
是的,这是有道理的。 不仅在物理学,而且在任何学科。 在金融领域,例如利率是以相反的时间间隔为单位(通常每年表示)。 钱有很多不同的单位。 它们之间的转换只能用交叉汇率进行,具有一种货币除以另一种货币的尺寸。 利息支付,股息支付,本金支付等通常以一定的频率发生。
它可以防止乘以两个值并以非法值结束。 它可以防止总计美元和欧元等
我并不是说你这样做是错的,但是我们正在为我正在进行的这个项目投入太多,坦率地说,我怀疑它的好处大于麻烦。 特别是如果你在一个团队中,好的variables命名(只是拼出来的东西),代码审查和unit testing将防止任何问题。 另一方面,如果你可以使用提升,单位可能是检查(我没有)的东西。
要检查types安全性,可以使用专用库。
最猖狂的使用是boost :: units,它完美的工作,没有执行时间的开销,很多function。 如果这个库在理论上解决你的问题。 从一个更实用的angular度来看,界面是如此尴尬和严重logging,你可能有问题。 编译时间越多,编译时间就越多,所以清楚地检查一下,在合理的时间内编译一个大的工程,才能使用它。
doc: http : //www.boost.org/doc/libs/1_56_0/doc/html/boost_units.html
另一种方法是使用unit_lite。 function比boost库less,但编译速度更快,界面更简单,错误消息更易读。 这个库需要C ++ 11。
代码: https : //github.com/pierreblavy2/unit_lite
链接到文档是在github描述(我不能发布超过2个链接在这里!!!)。
我在Boost.Units图书馆的CPPcon 2015上做了一个教程演示。 这是一个强大的库,每个科学应用程序应该使用。 但由于文档不好,很难使用。 希望我的教程可以帮助这个。 你可以在这里find幻灯片/代码: