如何在c ++接口中处理单位

sch*_*ufi 21 c++

我目前正在设计一个API,我希望用户能够编写如下代码:

PowerMeter.forceVoltage(1 mV);
PowerMeter.settlingTime(1 ms);
Run Code Online (Sandbox Code Playgroud)

目前我们使用以下定义执行此操作:

#define mV *1.0e-03
Run Code Online (Sandbox Code Playgroud)

这使得用户编写代码非常方便,并且它也非常易读,但当然也有缺点:

int ms;
Run Code Online (Sandbox Code Playgroud)

会抛出一些难以理解的编译器错误.所以我正在寻找更好的解决方案.

我尝试了新的C++ 11文字,但是我可以实现的是:

long double operator "" _mV(long double value) {
  return value * 1e-3;
}
PowerMeter.forceVoltage(1_mV);
Run Code Online (Sandbox Code Playgroud)

最后,API并不关心像Volt或第二个这样的单位,而只关注数字,所以我不想做任何检查,如果你真的输入伏特的强制电压.所以这也应该是可能的:

PowerMeter.forceVoltage(2 ms);
Run Code Online (Sandbox Code Playgroud)

除了坚持定义之外还有什么想法?

And*_*rsK 18

如何通过为不同的电流创建类(ms,mV)来改变它

例如

PowerMeter.forceVoltage( mV(1) );  
PowerMeter.settlingTime( ms(1) )
Run Code Online (Sandbox Code Playgroud)

这对用户来说非常清楚,并且可以说难以阅读,而且您可以免费获得类型检查.具有不同单元的公共基类将使其更容易实现.

  • Boost.Date_Time将此方法用于其`time_duration`类型(http://www.boost.org/doc/libs/1_49_0/doc/html/date_time/posix_time.html#date_time.posix_time.time_duration). (3认同)

gah*_*cep 9

你可以看到Calum Grant 的库" C++ Units "作为如何实现它的一个很好的例子.该库有点过时,但仍值得观看或可能会使用.

此外,我认为可能有趣的是:" SI单位应用模板元编程:基于单元的计算库 "

还有一个好的图书馆:UDUNITS-2,其中:

包含物理量单位的C库以及单位定义和价值转换实用程序.

  • +1超越比率,**尺寸**是最重要的部分.随着尺寸的确定,比率(几乎)是免费的. (2认同)

jua*_*nza 8

您可以使用C++ 11 对单元的编译时合理算术支持,而不是为单元定义文字或宏.


Dan*_*bić 6

看看Boost.Units.这是一些示例代码:

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.
Run Code Online (Sandbox Code Playgroud)


Tho*_* M. 2

我更喜欢尽可能避免使用宏,这是一个应该可以做到的例子。一种为您提供正确尺寸的轻量级解决方案是:

static double m = 1;
static double cm = 0.1;
static double mV = 0.001;

double distance = 10*m + 10*cm;
Run Code Online (Sandbox Code Playgroud)

这也反映了单位是与值相乘的物理概念。

  • 附加评论:您可能希望为此使用命名空间,然后 API 的用户可以决定是否喜欢混乱他的命名空间或执行 setVoltage(10 * CoolUnits::m)。但仍然比定义东西更好。 (2认同)