使用gcc和operator ""s来处理std::chrono

5

我想使用 std::chrono::duration 字面量,例如 10s 表示“10秒”,就像这样:

std::chrono::duration<uint64_t, std::milli> millisecs = 10s;

但是,我遇到了这个错误:
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

我已经在我的gcc编译命令中添加了-fext-numeric-literals

g++ -fext-numeric-literals --std=c++17 -Wall -pedantic -Wextra \
    main.cpp -O0 -g -o go

我做错了什么?


2
你是否有适当的“using namespace”指令? - Mat
@Mat:运算符使用哪个命名空间? - Klaus
2
http://en.cppreference.com/w/cpp/chrono/operator%22%22s - Mat
2
@Mat:好的,我明白了。谢谢!将其设为答案以接受它 ;) - Klaus
2个回答

6

您需要添加相应的命名空间(namespace)

 using namespace std::chrono_literals;

'chrono_literals' 不是命名空间名称。 - Andrey
你是什么意思?那是什么?! - Keivan
在添加命名空间后抛出了异常。从其他线程中发现它与旧的C++版本(<=11)不兼容。 - Andrey

0

别忘了使用 using namespace 声明以访问 std::chrono::duration<> 文字

我进行了一些尝试和学习,您可以在这里查看:chrono_duration_literals__using_declaration.cpp

关键要点:

要使用 std::chrono::duration<> 文字,例如"30秒"的 30s,在此语句中:

std::chrono::seconds halfmin = 30s;

...你必须使用适当的using namespace声明,例如:

// 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;

...或者你可以省略那些using namespace声明,但是你必须显式地将整数转换为std::chrono::duration<>类型,例如,转换为std::chrono::seconds,它是std::chrono::duration<int64_t, ratio<1, 1>>的typedef:

std::chrono::seconds halfmin = std::chrono::seconds(30);

我学习上述4个using namespace选项的主要来源是这里:std::literals::chrono_literals::operator""s。这是关于秒的s字面运算符的页面。该运算符被称为operator""s()

无论如何,cppreference.com社区维基都提供了一些非常有价值的信息(重点加粗):

注释

这些运算符在命名空间std::literals::chrono_literals中声明,其中literalschrono_literals都是inline命名空间。可以通过using namespace std::literalsusing namespace std::chrono_literalsusing namespace std::literals::chrono_literals来访问这些运算符。

此外,在命名空间std::chrono中,标准库提供了指令using namespace literals::chrono_literals;,因此如果程序员使用using namespace std::chrono来访问chrono库中的类,则相应的字面量运算符也会变得可见。

std::string还定义了operator""s,用于表示std::string类型的字面对象,但它是一个字符串字面量:10s表示十秒,但"10"s是一个两个字符的字符串。

如果省略了using namespace声明,你就需要使用这些超长的强制类型转换选项

这些选项同样适用于不包含上述using namespace声明的情况,但它们使用起来相当繁琐:

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!

如果你想要类似于C语言的简单性而不是使用std::chrono

...那么可以使用我的millis()micros()nanos()函数!

这样,你就可以轻松地获取时间戳,例如:

// 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();

请查看我的答案和库:

  1. 这里是如何在C++中获取类似于C语言的毫秒、微秒和纳秒时间戳的简单方法:
  2. 如何在C语言中获取一个简单的时间戳
  3. 我的Linux C和C++ timinglib.h 时间戳和计时库。它有一些非常方便的 sleepsleep_until 函数,还允许你在Linux中启用软实时 SCHED_RR 轮询调度程序,将x86-64 Linux中的睡眠分辨率从约55微秒提高到约4微秒。
    1. 我经常使用并更新这个库。它很棒。
    2. timinglib.h
    3. timinglib.c
  4. 我在Linux上使用我的 sleep_until_us() 函数的10 KHz周期循环示例:如何在Linux中轻松运行高分辨率、高精度的周期循环,以任何频率(例如10 KHz)使用软实时调度程序和纳秒延迟

auto halfmin = std::chrono_seconds(30); 有什么问题吗?它在你的非使用命名空间示例中缺失了... - bloody

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接