C ++:使用后缀设置时间

时间:2019-05-19 20:32:02

标签: c++ c++11 time c++14 user-defined-literals

告诉我,C ++ 11/14/17中是否可以存在以下内容:

1)使用时间后缀设置时间

double time1 = 1s; // time1 = 1.0
double time2 = 2m; // time2 = 120.0
double time3 = 7ms; // time3 = 0.007 

2)以设置的后缀获取时间的字符串值

std::cout << getTime(time1); // cout 1s
std::cout << getTime(time2); // cout 2s
std::cout << getTime(time3); // cout 7ms

4 个答案:

答案 0 :(得分:2)

  1. 是的,从C ++ 14开始,您可以使用用户定义的文字described here创建持续时间:

    #include <chrono>
    using namespace std::literals;
    auto time1 = 1s; // std::chrono::seconds{1}
    auto time2 = 2min; // std::chrono::minutes{2}
    auto time3 = 7ms; // std::chrono::milliseconds{7}
    

    这些创建存储整数值的类型安全对象。您可以在内部相当容易地使用double,但是这些专业化并没有附带漂亮的类型别名:

    namespace chr = std::chrono;
    using dbl_seconds = chr::duration<double, chr::seconds::period>;
    // Likewise for other units
    dbl_seconds time1 = 1s;
    

    如果您绝对需要内部值(通常是个坏主意),则可以使用.count()来访问它。

  2. 这计划在C ++ 20中出现:

    std::cout << time1; // 1s, or 1.000000s if using double
    

    直到那时,您对标准C ++所做的最好的工作就是将其吸收并使用count()

    std::cout << time1.count() << 's'; // 1s
    

要深入了解库,请观看Howard's CppCon talk。他的其他演讲涉及计划的C ++ 20新增功能。

答案 1 :(得分:1)

所有现代C ++时间实用程序均在the reference for <chrono> library

中进行了描述
  1. ,从开始,我们有了std::literals::chrono_literals, 允许我们使用以下文字:

    operator""h
    operator""min
    operator""s
    operator""ms
    operator""us
    operator""ns
    

    例如(来自 cppreference):

    #include <iostream>
    #include <chrono>
    
    int main()
    {
        using namespace std::chrono_literals;
        auto day = 24h;
        auto halfhour = 0.5h;
        std::cout << "one day is " << day.count() << " hours\n"
                  << "half an hour is " << halfhour.count() << " hours\n";
    }
    

  1. 不直接,但是从开始存在 std::chrono::duration, 带有几种方便的帮助程序类型,可帮助正确描述时间 (例如std::chrono::millisceondsstd::chrono::hours等)。使用 这些,您可以轻松地执行所需的操作。

    简化示例 cppreference。 如您所见,单位必须单独打印,但是选择 借助一些模板魔术,可以轻松打印正确的单元。

    #include <iostream>
    #include <chrono>
    
    int main()
    {     
        std::chrono::seconds sec(1);
    
        std::cout << sec.count() <<" second is equal to:\n";
    
        // integer scale conversion with no precision loss: no cast
        std::cout << std::chrono::microseconds(sec).count() << " microseconds\n";
    
        // integer scale conversion with precision loss: requires a cast
        std::cout << std::chrono::duration_cast<std::chrono::minutes>(sec).count()
                  << " minutes\n";
    }
    

答案 2 :(得分:1)

  1. ,通过std::chrono_literals

  2. 不直接,但您可以自己打印typeid(可用于调试)或提供重载流持续时间。

我在此处包括了operator<<的显式重载,但是作为 @JeJo ,也可以使用模板来完成:https://wandbox.org/permlink/o495eXlv4rQ3z6yP

#include <iostream>
#include <chrono>
#include <typeinfo>

using namespace std::chrono_literals;

// example overloads for streaming out durations
std::ostream& operator<<(std::ostream& os, const std::chrono::nanoseconds& v) {
    return os << v.count() << "ns";
}
std::ostream& operator<<(std::ostream& os, const std::chrono::microseconds& v) {
    return os << v.count() << "us";
}
std::ostream& operator<<(std::ostream& os, const std::chrono::milliseconds& v) {
    return os << v.count() << "ms";
}
std::ostream& operator<<(std::ostream& os, const std::chrono::seconds& v) {
    return os << v.count() << "s";
}
std::ostream& operator<<(std::ostream& os, const std::chrono::minutes& v) {
    return os << v.count() << "min";
}
std::ostream& operator<<(std::ostream& os, const std::chrono::hours& v) {
    return os << v.count() << "h";
}

int main() {
    auto time1 = 1s;
    auto time2 = 2min;
    auto time3 = 7ms;
    std::cout << time1.count() << " " << typeid(time1).name() << "\n";
    std::cout << time2.count() << " " << typeid(time2).name() << "\n";
    std::cout << time3.count() << " " << typeid(time3).name() << "\n";
    std::cout << time1 << "\n";
    std::cout << time2 << "\n";
    std::cout << time3 << "\n";
}

可能的输出:

1 NSt6chrono8durationIlSt5ratioILl1ELl1EEEE
2 NSt6chrono8durationIlSt5ratioILl60ELl1EEEE
7 NSt6chrono8durationIlSt5ratioILl1ELl1000EEEE
1s
2min
7ms

答案 3 :(得分:-1)

1)否

2)不,不是直接。存在运算符可以转换为chrono类型(尽管是整数而不是double),但是它们没有operator<<重载。 boost::chrono拥有漂亮的打印机(不过不推荐使用)。但是,它们已被完全写出,而不仅仅是简短形式。

请参阅: