现在我们很快就有了用户定义的文字(UDL),例如在 GCC 4.7 中,我急切地等待(物理)单元库(例如Boost.Units )使用它们来简化文字的表达,例如1+3i
,或. 有没有人使用支持这种行为的 UDL为Boost.Units编写了扩展?3m
3meter
13_meter
2 回答
没有人提出这样的扩展。只有 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_
但至少我可以构建真正的单位表达式。