Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::chrono::time_point compiler error when converting from a variable

I have a variable of type long long that represents a time point in nanoseconds.

I'm trying to wrap it using std::chrono::time_point yet the compiler (VS 2017) is giving me troubles.

here is a code that compiles:

std::chrono::time_point<std::chrono::steady_clock> tpStart(std::chrono::nanoseconds(10ll));
std::chrono::time_point<std::chrono::steady_clock> tpEnd = std::chrono::steady_clock::now();
double d =  std::chrono::duration<double>(tpEnd - tpStart).count();

Now if i switch the value 10ll with a variable, the line that computes the duration fails to compile:

constexpr long long t = 10ll;
std::chrono::time_point<std::chrono::steady_clock> tpStart(std::chrono::nanoseconds(t));
std::chrono::time_point<std::chrono::steady_clock> tpEnd = std::chrono::steady_clock::now();
double d =  std::chrono::duration<double>(tpEnd - tpStart).count();

Here is the error code:

error C2679: binary '-': no operator found which takes a right-hand operand of type 'overloaded-function' (or there is no acceptable conversion)

Any Idea why is this happening? how can I convert a variable of type long long to a std::chrono::time_point?

like image 832
Elad Maimoni Avatar asked Jun 16 '19 12:06

Elad Maimoni


People also ask

What is std :: Chrono :: Time_point?

Class template std::chrono::time_point represents a point in time. It is implemented as if it stores a value of type Duration indicating the time interval from the start of the Clock 's epoch. Clock must meet the requirements for Clock or be std::chrono::local_t (since C++20).

What does std :: Chrono :: System_clock :: now return?

std::chrono::system_clock::now Returns a time point representing with the current point in time.

What is std :: Chrono :: Steady_clock?

Class std::chrono::steady_clock represents a monotonic clock. The time points of this clock cannot decrease as physical time moves forward and the time between ticks of this clock is constant.

What is std:: chrono:: duration?

Class template std::chrono::duration represents a time interval. It consists of a count of ticks of type Rep and a tick period, where the tick period is a compile-time rational fraction representing the time in seconds from one tick to the next. The only data stored in a duration is a tick count of type Rep .


1 Answers

TLDR : It's a most vexing parse case

prog.cc:8:59: warning: parentheses were disambiguated as a function declaration [-Wvexing-parse]
std::chrono::time_point<std::chrono::steady_clock> tpStart(std::chrono::nanoseconds(t));

Fix with {} instead of ()

constexpr long long t = 10ll;
std::chrono::time_point<std::chrono::steady_clock> tpStart{std::chrono::nanoseconds{t}};
std::chrono::time_point<std::chrono::steady_clock> tpEnd = std::chrono::steady_clock::now();
double d =  std::chrono::duration<double>(tpEnd - tpStart).count();

Why it's a most vexing parse?

std::chrono::time_point<std::chrono::steady_clock> pStart  (std::chrono::nanoseconds(t));
//                  ^^^^ Type 1 ^^^^^              ^name^      ^^^^ Type 2 ^^^^

So we can reproduce with :

constexpr long long t = 10ll;
int fail (double (t) );
fail = 6; // compilation error here

Why ? Let's remove some noise :

int fail (double (t) );
//  <=> 
int fail (double t);
// <=>
int fail (double) ; // Most vexing parse.

We can fix it by switching to {}

int Ok {double {t} };
like image 94
Martin Morterol Avatar answered Oct 01 '22 01:10

Martin Morterol