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

发布于 2025-01-04 14:55:55 字数 235 浏览 0 评论 0原文

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

Now that we soon have user defined literals (UDL), in GCC 4.7 for example, I'm eagerly waiting for (physical) unit libraries (such as Boost.Units) using them to ease expression of literals such as 1+3i, 3m, 3meter or 13_meter. Has anybody written an extension to Boost.Units using UDL supporting this behaviour?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

毁我热情 2025-01-11 14:55:55

还没有人提出这样的扩展。只有 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;
}

我认为浏览您最喜欢的单元并执行此操作不会太难。

关于将它们放入库中:
文字运算符是命名空间作用域函数。后缀的竞争将会变得非常激烈。我会(如果我是 boost)

namespace literals
{
...
}

然后 Boost 用户可以

using boost::units::literals;

与您通常使用的所有其他使用 decl 一起完成。那么你就不会被 std::tr2::units 等问题所困扰。同样,如果你自己推出。

No one has come out with such an extension. Only gcc (and possibly IBM?) has UDL so it might be a while. I'm hoping some kind of units makes it into tr2 which is starting about now. If that happens I'm sure UDL for units will come up.

This works:

//  ./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;
}

I think it wouldn't be too hard to go through you favorite units and do this.

Concerning putting these in a library:
The literal operators are namespace scope functions. The competition for suffixes is going to get ugly. I would (if I were boost) have

namespace literals
{
...
}

Then Boost users can do

using boost::units::literals;

along with all the other using decls you typically use. Then you won't get clobbered by std::tr2::units for example. Similarly if you roll your own.

泛滥成性 2025-01-11 14:55:55

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

In my opinion there is not much gain in using literals for Boost.Units, because a more powerful syntax can still be achieved with existing capabilities.

In simple cases, looks like literals is the way to go, but soon you see that it is not very powerful.
For example, you still have to define literals for combined units, for example, how do you express 1 m/s (one meter per second)?

Currently:

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

but with literals?

// 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

A better solution can be achieved with existing features. And this is what I do:

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;

In the same way you can do: auto a = 1.*m/pow<2>(s); or extend the abbreviations more if you want (e.g. static const area m2 = pow<2>(si::meter);)

What else beyond this do you want?

Maybe a combined solution could be the way

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

but there will be so much redundant code and the gain is minimal (replace * by _ after the number.)

One drawback of my solution is that it polutes the namespace with common one letter names. But I don't see a way around that except to add an underscore (to the beginning or the end of the abbreviation), as in 1.*m_/s_ but at least I can build real units expressions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文