【问题标题】:How to find duration (time) units in C++11如何在 C++11 中查找持续时间(时间)单位
【发布时间】:2012-10-18 18:23:46
【问题描述】:

我想要一个PrintDuration 函数来打印任务花费了多长时间,并允许用户指定打印的单位。用法示例:

auto start = std::chrono::system_clock::now();
std::this_thread::sleep_for(std::chrono::seconds(3));
PrintDuration<std::chrono::microseconds>(std::cout, start, "Waited for:");

它会打印出类似:"Waited for: 3000000μs\n"

我的问题是:如何找到用户提供的单位?

目前,我正在使用以下内容:

template <class T>
std::intmax_t GetNum(const T& duration)
{
    return T::period::num;
}

template <class T>
std::intmax_t GetDen(const T& duration)
{
    return T::period::den;
}


typedef std::chrono::time_point<std::chrono::system_clock> TimePoint_t;

template <class Duration = std::chrono::seconds>
void PrintDuration(std::ostream& output,
                   const TimePoint_t& start,
                   std::string message) 
{
    auto duration = std::chrono::system_clock::now() - start;
    auto convertedDuration = std::chrono::duration_cast<Duration>(duration);
    auto count = convertedDuration.count();

    std::string units("");

    if (GetNum(convertedDuration) == 1)
    {
        if (GetDen(convertedDuration) == std::nano::den)    
            units = "ns";
        else if (GetDen(convertedDuration) == std::micro::den)
            units = "\u03BCs"; // us
        else if (GetDen(convertedDuration) == std::milli::den)
            units = "ms";
        else if (GetDen(convertedDuration) == 1)
            units = "s";
        else
            units = "";
    }
    else if(GetDen(convertedDuration) == 1)
    {
        if (GetNum(convertedDuration) == 60)
            units = "m";
        else if (GetNum(convertedDuration) == 3600)
            units = "h";
        else
            units = "";
    }

    output << message << ' ' << count << units << '.' << std::endl;
}

虽然效果很好,但看起来很冗长。我查看了 C++ 的文档,但找不到。非常感谢任何帮助。

【问题讨论】:

    标签: c++ templates time c++11


    【解决方案1】:

    你可以这样写:

    template <typename T>
    const wchar_t* GetUnits(T) { return L"unknown units"; }
    
    template<>
    const wchar_t* GetUnits(std::chrono::nanoseconds) { return L"ns"; }
    
    template<>
    const wchar_t* GetUnits(std::chrono::microseconds) { return L"\u03BCs"; }
    
    template<>
    const wchar_t* GetUnits(std::chrono::milliseconds) { return L"ms"; }
    
    typedef std::chrono::time_point<std::chrono::system_clock> TimePoint_t;
    
    template <class Duration>
    void PrintDuration(std::wostream& output, const TimePoint_t& start, const std::wstring& message) 
    {
        auto duration = std::chrono::system_clock::now() - start;
        auto convertedDuration = std::chrono::duration_cast<Duration>(duration);
    
        output << message << L" " << convertedDuration.count() << GetUnits(convertedDuration) << L"." << std::endl;
    }
    
    int main(int /*argc*/, char* /*argv*/[])
    {
        auto start = std::chrono::system_clock::now();
        std::this_thread::sleep_for(std::chrono::seconds(3));
        PrintDuration<std::chrono::microseconds>(std::wcout, start, L"Waited for:");
        return 0;
    }
    

    【讨论】:

    • 请不要为此使用函数模板特化,只是重载。
    • 谢谢,我正在考虑这个问题。我想它有点整洁,但仍然很冗长。我不明白为什么标准中没有像std::get_units(duration) 这样的东西:-(
    • 顺便说一句,Xeo,我认为你不能只用重载来做到这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-18
    • 1970-01-01
    • 1970-01-01
    • 2021-08-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多