-
Notifications
You must be signed in to change notification settings - Fork 93
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: value_cast<Unit, Representation>
added
#516
Conversation
docs/getting_started/faq.md
Outdated
To prevent such issues and make similar conversions safe by construction, we've added the following: | ||
|
||
```cpp | ||
Scaled spx1 = value_cast<USD_s, std::int64_t>(price1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The trend to require explicit units indeed results in safer code that doesn't unexpectedly change meaning over time.
However, consider the inverse, where price1
is represented with std::int64_t
, and you're casting to double
.
You probably want the representation conversion first, and then the scaling for the unit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I worded this wrongly in FAQ, but I think it will also work with the current implementation. I have to confirm that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Confirmed!
std::cout << value_cast<si::second, double>(42 * us) << "\n";
prints:
4.2e-05 s
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the representation conversion happening first?
What about something more extreme like value_cast<si::nanosecond, double>(42 * Ts)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The trend to require explicit units indeed results in safer code that doesn't unexpectedly change meaning over time.
Please note that it is not to future-proof the cast but to make the conversion correct in the first place. Without it, the value was truncated, and the result was invalid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about something more extreme like
value_cast<si::nanosecond, double>(42 * Ts)
?
std::cout << value_cast<si::nano<si::second>, double>(42 * Ts) << "\n";
prints:
4.2e+22 ns
I just realized that we could try a similar practice to https://abseil.io/docs/cpp/guides/strings#adaptation-to-returned-types here. Although I do not know if it would not be an over-engineering? With this, we could just write |
Yes, and it doesn't work if you don't have a concrete target type. |
What is the status of that proposal? Given that it's quite old now, I'm guessing it's gone dormant. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The thrust of this PR is to make the unit into a mandatory first template argument for value_cast
, right?
If we land this, what is the way for users to change the rep without repeating the unit (similar to Au's rep_cast
)?
Yeah, you can't even find it at https://github.com/cplusplus/papers/issues?q=is%3Aissue+P0672. |
This is exactly what we want to prevent. Such an interface is error-prone as I proved it in https://godbolt.org/z/M8WaeK3f3 and described in the FAQ section in this PR. Do you think that we can somehow expose such an interface but still prevent such issues? The only idea I have is to use something like: https://abseil.io/docs/cpp/guides/strings#adaptation-to-returned-types which sucks. |
I agree that the example shows it's error prone, but I'm not sure how error prone. The downside of removing all It's an analogous problem to Au's old "explicit rep" syntax for forcing conversions. If On the other hand... experience suggests that So, does the value in preventing these bugs outweigh the extra typing and the obscuring of intent? I think either answer could be reasonable. For my part, I'm planning to keep |
All that said --- I think introducing a syntax that simultaneously specifies the target unit and rep is a long-needed and welcome addition. I'd prefer the syntax listed in the table from #477, but I think the most important thing is to simply have some way to spell that. |
This comment was marked as resolved.
This comment was marked as resolved.
This one: #477 (comment) i.e., the fuller, more comprehensive one. |
Thanks for your feedback.
Yeah, this is why I created this PR rather than doing the change directly on the mainline.
I am not so sure if that is that needed. In many cases it is still safer to write
Yes, me too. But the I am not sure what to do with it now. The new function is needed because this issue just proved it can't be |
Ideally, the unit-and-rep syntax should be not-truncating. In Au, it has always been truncating, but this was a mistake on my part that stemmed from conflating two different aspects of the I also think it's critically important to be able to specify the destination type at the time the conversion takes place. For example, consider So, to sum up:
|
value_cast<Representation>
replaced with value_cast<Unit, Representation>
value_cast<Unit, Representation>
added
No description provided.