C ++: установка времени с использованием суффиксов - PullRequest
1 голос
/ 19 мая 2019

Подскажите, может ли в C ++ существовать 14.11.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 ]

2 голосов
/ 19 мая 2019
  1. Да, начиная с C ++ 14, вы можете использовать пользовательские литералы , описанные здесь , для создания длительностей:

    #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
    

Чтобы лучше заглянуть в библиотеку, смотрите Говард CppCon Говарда . Другие его доклады посвящены планируемым дополнениям C ++ 20.

1 голос
/ 19 мая 2019

Все современные утилиты времени C ++ описаны в справочнике для <chrono> библиотеки

  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";
    }
    

Не напрямую , но начиная с существует std::chrono::duration, с несколькими удобными вспомогательными типами, помогающими правильно описать время(например, std::chrono::millisceonds, std::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";
}
1 голос
/ 19 мая 2019
  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
0 голосов
/ 19 мая 2019

1) Нет

2) Нет, не напрямую.Существуют операторы для преобразования в типы хроно (хотя это целые числа, а не двойные), но у них нет перегрузок operator<<.boost::chrono имеет красивые принтеры (хотя они устарели).Однако они полностью выписаны, а не только краткая форма.

См .:

...