12

I was looking at some code that used duration_cast. Looking a it I wondered why a static_cast was not used since static_cast's purpose in life is to convert between types.

Why did C++ need a new operator to convert between times? Why was static_cast not used?


Maybe I don't appreciate the difference C++ is making between milli-seconds, micro-seconds, nano-seconds, etc. For some reason, I thought the answer would be obvious or discussed on Stack Overflow, but I have not found it (yet).

4
  • 2
    duration_cast performs a mathematical calculation to translate between two durations of different measurements. A static_cast can only be done between classes in a related hierarchy. A duration_cast translates between two classes that have absolutely no relationship, whatsoever, with each other. Commented May 31, 2017 at 0:55
  • 4
    The main difference is that static_cast is built into the compiler, while duration_cast is a template in the standard library. Commented May 31, 2017 at 1:04
  • Thanks @dasblinkenlight. It did not occur to me that duration_cast was not an operator (awful c++ engineering). Should I delete this question? Commented May 31, 2017 at 1:16
  • @jww This is up to you - I think the question makes perfect sense, because the naming of the template function is really awkward. Commented May 31, 2017 at 3:32

2 Answers 2

10

There is already direct conversion of time intervals when there is no risk of loss of precision. duration_cast is required when there is a risk of loss of precision.

duration_cast is therefore not so much an operator as a deliberate conversion.

static_cast is not suitable since different duration types are not related. They are entirely different classes which happen to support the same concept.

e.g.:

#include <chrono>

int main()
{
  using namespace std::literals;

  // milliseconds    
  auto a = 10ms;

  // this requires a duration-cast
  auto lossy = std::chrono::duration_cast<std::chrono::seconds>(a);

  // but this does not
  auto not_lossy = std::chrono::nanoseconds(a);
}
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks @Richard. Part (most?) of my confusion was believing it was a built-in operator because of the way it was named. In fact, I called it an operator in the question, and dasblinkenlight picked up on it. If you add something about it not being an operator, then I should be able to accept.
@jww I've just read the comments. I appreciate your concern over naming, but consider also dynamic_pointer_cast, static_pointer_cast, et al. This concept of a non-language-level cast has previous form.
Thanks @Richard. At the risk of sounding argumentative (its really just a naive view of things since I'm not on the cutting edge).... C++ uses X_cast as operators (like static_cast); and C++11 started the trend of to_X (like to_string). It seems like it would have been less confusing to use to_duration.
@jww sure that could have worked. However, never underestimate the influence of the c++11 standard's progeny in the boost library.
boost::chrono came from (at the time draft) std::chrono, not vice-versa. The draft std::chrono came from this paper: open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2661.htm
|
5

I have revisited that question a lot over the years, and I now think that may have been a design mistake on my part.

I am currently experimenting with depending more on explicit conversion syntax for conversions that should not be made implicitly, rather than "named conversion syntax".

For example:

https://howardhinnant.github.io/date/date.html#year

year y = 2017_y;
int iy = int{y};  // instead of iy = y.to_int()

2 Comments

are there pro/con thoughts materialized somewhere on the web?
I've written them down here and there, but there's no paper dedicated to this subject. The advantage I see is uniform conversion syntax. This should not only make generic code easier to write, but it should also make it easier to learn new API's because you no longer have to remember how to spell to_int, or as_int, or get, or whatever. There are only implicit conversions and explicit conversions: T t = u; and auto t = T{u};.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.