物理增强.单位用户定义的文字

Physical Boost.Units User Defined Literals

本文关键字:定义 文字 用户 单位 增强      更新时间:2023-10-16

现在我们很快就有了用户定义的文字(UDL),例如在GCC 4.7中,我急切地等待(物理)单元库(如Boost.Units)使用它们来简化文字的表达,如1+3i3m3meter13_meter。是否有人使用UDL为Boost.Units编写了支持这种行为的扩展?

没有人提出这样的扩展。只有gcc(可能还有IBM?)有UDL,所以这可能需要一段时间。我希望某种单位能进入tr2,它大约现在开始。如果发生这种情况,我相信单位的UDL会出现。

这项工作:

//  ./bin/bin/g++ -std=c++0x -o units4 units4.cpp
#include <boost/units/unit.hpp>
#include <boost/units/quantity.hpp>
#include <boost/units/systems/si.hpp>
using namespace boost::units;
using namespace boost::units::si;
quantity<length, long double>
operator"" _m(long double x)
{ return x * meters; }
quantity<si::time, long double>
operator"" _s(long double x)
{ return x * seconds; }
int
main()
{
  auto l = 66.6_m;
  auto v = 2.5_m / 6.6_s;
  std::cout << "l = " << l << std::endl;
  std::cout << "v = " << v << std::endl;
}

我认为通过你最喜欢的单元并做到这一点不会太难。

关于将这些放入图书馆:文字运算符是命名空间作用域函数。后缀的竞争会越来越激烈。我会(如果我被提升的话)有

namespace literals
{
...
}

然后Boost用户可以进行

using boost::units::literals;

以及您通常使用的所有其他使用decl。那么你就不会被std::tr2::units打得落花流水了。同样,如果你自己滚动。

在我看来,使用Boost.Units的文字并没有多大好处,因为使用现有功能仍然可以实现更强大的语法。

在简单的情况下,看起来文字是一条路,但很快你就会发现它并不是很强大。例如,您仍然需要定义组合单位的文字,例如,如何表示1 m/s(每秒一米)?

目前:

auto v = 1*si::meter/si::second; // yes, it is long

但是用文字?

// fake code
using namespace boost::units::literals;
auto v = 1._m_over_s; // or 1._m/si::second; or 1._m/1_s // even worst

使用现有功能可以获得更好的解决方案。这就是我所做的:

namespace boost{namespace units{namespace si{ //excuse me!
namespace abbreviations{
    static const length             m   = si::meter;
    static const time               s   = si::second;
    // ...
}
}}} // thank you!
using namespace si::abbreviations;
auto v = 1.*m/s;

用同样的方法,你可以做:auto a = 1.*m/pow<2>(s);或者如果你想的话,可以扩展缩写(例如static const area m2 = pow<2>(si::meter);

除此之外,你还想要什么?

也许组合解决方案可能是

auto v = 1._m/s; // _m is literal, /s is from si::abbreviation combined with operator/

但是会有太多的冗余码并且增益是最小的(在数字之后用_代替*

我的解决方案的一个缺点是,它用常见的单字母名称来填充名称空间。但除了在缩写的开头或结尾添加下划线之外,我看不到任何解决方法,就像在1.*m_/s_中一样,但至少我可以构建实单位表达式。