Как обобщить std :: chrono :: duration (s)? - PullRequest
0 голосов
/ 12 октября 2019

Я написал три версии алгоритма для своего университетского класса.

Одна - грубая сила, другая - жадная, а последняя - эвристическая.

Я хочу быть в состоянии измерить, скольковремя, необходимое для выполнения каждого из алгоритмов.

Я использую библиотеку <chrono> для достижения этого

Прямо сейчас мой код выглядит так:

#include <iostream>
#include <chrono>
#include <sstream>

using namespace std;

string getTimeElapsed(long time1, const string &unit1, long time2 = 0, const string &unit2 = "") {
    stringstream s;
    s << time1 << " [" << unit1 << "]";
    if (time2) s << " " << time2 << " [" << unit2 << "]";
    return s.str();
}

int main() {
    auto begin = chrono::system_clock::now();
    // algorithm goes here
    auto solution = /* can be anything */
    auto end = chrono::system_clock::now();
    auto diff = end - begin;

    string timeElapsed;
    auto hours = chrono::duration_cast<chrono::hours>(diff).count();
    auto minutes = chrono::duration_cast<chrono::minutes>(diff).count();
    if (hours) {
        minutes %= 60;
        timeElapsed = getTimeElapsed(hours, "h", minutes, "min");
    } else {
        auto seconds = chrono::duration_cast<chrono::seconds>(diff).count();
        if (minutes) {
            seconds %= 60;
            timeElapsed = getTimeElapsed(minutes, "min", seconds, "s");
        } else {
            auto milliseconds = chrono::duration_cast<chrono::milliseconds>(diff).count();
            if (seconds) {
                milliseconds %= 1000;
                timeElapsed = getTimeElapsed(seconds, "s", milliseconds, "ms");
            } else {
                auto microseconds = chrono::duration_cast<chrono::microseconds>(diff).count();
                if (milliseconds) {
                    microseconds %= 1000;
                    timeElapsed = getTimeElapsed(milliseconds, "ms", microseconds, "μs");
                } else {
                    auto nanoseconds = chrono::duration_cast<chrono::nanoseconds>(diff).count();
                    if (microseconds) {
                        nanoseconds %= 1000;
                        timeElapsed = timeElapsed = getTimeElapsed(microseconds, "μs", nanoseconds, "ns");
                    } else timeElapsed = getTimeElapsed(nanoseconds, "ns");
                }
            }
        }
    }

    cout << "Solution [" << solution << "] found in " << timeElapsed << endl;

    return 0;
}

КакВы можете видеть, что составленные if-else предложения выглядят действительно некрасиво, и вы можете увидеть шаблон здесь:

if (timeUnit) { 
    timeElapsed = /* process current time units */
} else {
    /* step down a level and do the same for smaller time units */
}

Я хотел бы сделать эту процедуру рекурсивной функцией.

Однако яПонятия не имею, какими должны быть параметры такой функции, потому что chrono::duration является шаблонной структурой (?)

Эта функция будет выглядеть примерно так:

string prettyTimeElapsed(diff, timeUnit) {
    // recursion bound condition
    if (timeUnit is chrono::nanoseconds) return getTimeElapsed(timeUnit, "ns");

    auto smallerTimeUnit = /* calculate smaller unit using current unit */
    if (timeUnit) return getTimeElapsed(timeUnit, ???, smallerTimeUnit, ???);
    else return prettyTimeElapsed(diff, smallerTimeUnit);
}

Я думалсделать это:

auto timeUnits = {chrono::hours(), chrono::minutes(), ..., chrono::nanoseconds()};

Тогда я мог бы взять указатель (или даже индекс) на единицу времени и передать его функции.

Проблема в том, что я незнать, как обобщать эти структуры.

CLion выдвигает ошибку Deduced conflicting types (duration<[...], ratio<3600, [...]>> vs duration<[...], ratio<60, [...]>>) for initializer list element type

...