mpusz / mp-units

The quantities and units library for C++
https://mpusz.github.io/mp-units/
MIT License
998 stars 79 forks source link

`q[m / s]` or `q.in(m / s)` #469

Closed mpusz closed 10 months ago

mpusz commented 1 year ago

First, I would like to state that I personally love the syntax that creates a reference based on quantity_spec and Unit:

quantity<isq::height[m]> q;

I wouldn't like to make the above gone.

However, yesterday I wrote the following example in our documentation:

auto q1 = 42 * W;
std::cout << q1 << "\n";
std::cout << q1[J / s] << "\n";
std::cout << q1[N * m / s] << "\n";
std::cout << q1[kg * m2 / s3] << "\n";

Initially, I provided this operator to entertain myself with this idea and for consistency with the above. However, there are a few significant differences here:

  1. isq::height[m] is a pure compile-time operation with no runtime overhead. It also never touches the quantity value.
  2. q[m], of course, creates a new type in compile-time but also involves a runtime value rescaling operation according to the provided new unit. It can also lead to overflows or losing the precision of a quantity value.

Even more, we now have a q.number_in(si::metre) (#412), which returns a raw value in a provided unit.

So here comes the questions:

  1. Should we add q.in(si:::metre) to express runtime behavior and for consistency with number_in()?
  2. Should we remove the q[si::metre]?
  3. Should we have both solutions?
JohelEGP commented 1 year ago
  1. Should we have both solutions?

q.in(si::metre).number() can replace q.number_in(si::metre).

mpusz commented 1 year ago

Well, we can also use q[si::metre].number() now.

mpusz commented 1 year ago

BTW, there is one more important difference in behavior between isq::height[m] and q[m]. The first one is provided unconditionally, while the second one is available only for non-truncating conversion. Otherwise value_cast<m>(q) needs to be used.

JohelEGP commented 1 year ago
  1. Should we have both solutions?

q.in(si::metre).number() can replace q.number_in(si::metre).

IIRC, the proponents of number_in suggested removing number because it's unsafe. So to get the number you have to specify the unit.

mpusz commented 1 year ago

On the other hand, q.number_in(m), as of now, has the same constraints as q[m].