'Using operator ""s for std::chrono with gcc
I want to use the std::chrono::duration literals, such as 10s to mean "10 seconds", like this:
std::chrono::duration<uint64_t, std::milli> millisecs = 10s;
But, I'm getting this error:
main.cpp:20:17: error: unable to find numeric literal operator 'operator""s' millisecs = 20s; main.cpp:22:17: note: use -std=gnu++11 or -fext-numeric-literals to enable more built-in suffixes
I already added -fext-numeric-literals to my gcc compilation command:
g++ -fext-numeric-literals --std=c++17 -Wall -pedantic -Wextra \
    main.cpp -O0 -g -o go
What am I doing wrong?
Solution 1:[1]
You should add the corresponding namespace:
 using namespace std::chrono_literals;
Solution 2:[2]
Don't forget a using namespace declaration to get access to std::chrono::duration<> literals
I did some playing around and learning that you can take a look at here: chrono_duration_literals__using_declaration.cpp.
Key takeaways:
To use std::chrono::duration<> literals like 30s for "30 seconds", ex: in this statement here:
std::chrono::seconds halfmin = 30s;
...you must use the appropriate using namespace declaration, such as:
// Use at least **one** of these!:
using namespace std::literals;
using namespace std::chrono_literals;  // [my preference]
using namespace std::literals::chrono_literals;
using namespace std::chrono;
...OR you can leave out those using namespace declarations, but then you must explicitly cast the integer to a std::chrono::duration<> type, like this, for example, to std::chrono::seconds, which is a typedef of std::chrono::duration<int64_t, ratio<1, 1>>:
std::chrono::seconds halfmin = std::chrono::seconds(30);
My main source for learning about the 4 using namespace options above was here: std::literals::chrono_literals::operator""s. This is the page for the s literal operator, for seconds. This operator is called operator""s().
Anyway, that cppreference.com community wiki states some really valuable information (emphasis added):
Notes
These operators are declared in the namespace
std::literals::chrono_literals, where bothliteralsandchrono_literalsareinlinenamespaces. Access to these operators can be gained withusing namespace std::literals,using namespace std::chrono_literals, andusing namespace std::literals::chrono_literals.In addition, within the namespace
std::chrono, the directiveusing namespace literals::chrono_literals;is provided by the standard library, so that if a programmer usesusing namespace std::chrono; to gain access to the classes in thechronolibrary, the corresponding literal operators become visible as well.
std::stringalso definesoperator""s, to represent literal objects of typestd::string, but it is a string literal:10sis ten seconds, but"10"sis a two-character string.
If you leave out the using namespace declaration, you have these crazy-long casting options
All of these options work too, withOUT including a using namespace declaration from above, but they are pretty irritating to use:
std::chrono::seconds halfmin = (std::chrono::seconds)30; // WORKS!
std::chrono::seconds halfmin = std::chrono::seconds(30); // WORKS! [My preference]
std::chrono::seconds halfmin = std::chrono::seconds{30}; // WORKS!
std::chrono::seconds halfmin = 
    std::chrono::duration<int64_t, std::ratio<1>>(30);   // WORKS!
std::chrono::seconds halfmin = std::chrono::duration<int64_t>(30); // WORKS!
auto halfmin = std::literals::chrono_literals::operator""s(30);    // WORKS!
std::chrono::duration<long double, std::ratio<1>> halfmin = 
    std::literals::chrono_literals::operator""s(30);               // WORKS!
std::chrono::seconds halfmin = 
    static_cast<std::chrono::seconds>(30);                         // WORKS!
std::chrono::seconds halfmin = 
    static_cast<std::chrono::duration<int64_t, std::ratio<1, 1>>>(30); // WORKS!
If you're looking for C-like simplicity instead of std::chrono
...then use my millis(), micros(), and nanos() functions instead!
Then you can get super-simple timestamps like this:
// millisecond timestamp with monotonic clock in C or C++
uint64_t time_ms = millis();
// microsecond timestamp with monotonic clock in C or C++
uint64_t time_us = micros();
// nanosecond timestamp with monotonic clock in C or C++
uint64_t time_ns = nanos();
See my answers and libraries:
- Here is how to get simple C-like millisecond, microsecond, and nanosecond timestamps in C++:
- How to get a simple timestamp in C
- My Linux C and C++ timinglib.htimestamp and timing library. It has some really convenientsleepandsleep_untilfunctions as well, and allows you turn on the soft real-timeSCHED_RRround-robin scheduler in Linux too, to improve sleep resolution in x86-64 Linux from ~55 us to ~4 us.- I keep this library up-to-date, and use it a lot. It's great.
- timinglib.h
- timinglib.c
 
- 10 KHz periodic loop example of mine on Linux using my sleep_until_us()function: How to run a high-resolution, high-precision periodic loop in Linux easily, at any frequency (ex: 10 KHz) using a soft real-time scheduler and nanosecond delays
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source | 
|---|---|
| Solution 1 | Keivan | 
| Solution 2 | 
