2012-02-13 27 views
7

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

+1

考虑到唯一支持UDL的编译器是GCC,即使只在不稳定版本中,我也猜不到。另外,不以'_'开始的UDL被保留用于未来的标准;你不能自己写。 – 2012-02-14 01:56:28

+0

很高兴知道!我只是想知道UDL如何与当前的数字文字后缀'l','f'和'd'冲突。 '_'要求回答了这个问题。 – 2012-02-14 20:01:58

回答

5

没有人有这样的延伸。只有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 
{ 
... 
} 

然后升压用户可以与其他所有使用decls您通常使用沿做

using boost::units::literals; 

。那么你就不会被std::tr2::units贬损。同样如果你推出自己的。

+1

烦恼#1:文字操作符只能使用几个参数类型。这将是很好的版本,返回浮动和双重以及长双倍,所以计算不会提升到长双倍所有时间? ADL不会按返回类型进行选择 - 特定于精度的名称空间和使用?啊。 – emsr 2012-02-14 03:55:42

+1

烦恼#2:除了所有的单位,至少有一个公倍数是很好的。例如不仅“m”而且“km”,“cm”,“mm”表示长度,“Hz”,“kHz”,“MHz”,“GHz”表示频率。它可能变得乏味 - 或者涉及一些宏。 – emsr 2012-02-14 03:59:43

+0

我想知道为什么要提高精度_对您来说是一个问题... – celticminstrel 2012-07-07 18:46:23

3

在我看来,在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_,但至少我可以构建真实单位表达式。