物理Boost.Units用户定义的文字

时间:2012-02-13 09:03:59

标签: c++ user-defined-literals boost-units

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

2 个答案:

答案 0 :(得分:4)

没有人提出这样的延期。只有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;

以及所有其他使用您通常使用的decls。然后你不会被std::tr2::units所摧毁。同样,如果你自己动手。

答案 1 :(得分:3)

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

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

目前:

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_中所示,但至少我可以构建真实的单位表达式。