如何正确地将boost :: optional <std :: chrono :: duration>用作函数参数?

时间:2018-07-20 21:45:25

标签: c++ c++11 templates boost chrono

我需要有一个接受boost::optional<std::chrono::duration>的函数。 我希望能够通过它,例如std::chrono::millisecondsstd::chrono::secondsboost::none

我有几种解决方案无法完全实现我想要的功能。

尝试1:

template <class PeriodT>
void foo(boost::optional<std::chrono::duration<int64_t, PeriodT>> duration);

尝试1的问题:

我不能简单地通过std::chrono::duration甚至boost::none。要通过boost::none,我必须执行以下操作:

boost::optional<std::chrono::seconds> input = boost::none;
foo(input);

我不能打电话

foo(boost::none); 

std::chrono::seconds input(10);
foo(input);

尝试2:

void foo(boost::optional<std::chrono::milliseconds> duration);

尝试2的问题:

自动转换不会发生。

foo(std::chrono::seconds(10));

将无法编译。

foo(std::chrono::milliseconds(10));

将会编译,

foo(boost::none);

有什么办法可以让我的函数完全接受boost::optional
任何代表/期间?

在我的实际用例中,该函数将需要接受这些可选持续时间的倍数,因此默认值对我不起作用。

1 个答案:

答案 0 :(得分:3)

#include "boost/optional.hpp"
#include <chrono>
#include <iostream>

void foo(boost::optional<std::chrono::milliseconds> duration)
{
    if (duration)
        std::cout << duration->count() << "ms\n";
    else
        std::cout << "none\n";
}

void foo(std::chrono::milliseconds duration)
{
    foo(boost::optional<std::chrono::milliseconds>{duration});
}

int
main()
{
    using namespace std::chrono;
    foo(10ms);
    foo(10s);
    foo(boost::none);
}

如果要接受任何 chrono::duration<Rep, Period>,则需要再添加一个重载并将所有内容模板化。另外,您还需要确定Rep的默认Periodboost::none

#include "boost/optional.hpp"
#include "date/date.h"
#include <chrono>
#include <iostream>

template <class Rep, class Period>
void foo(boost::optional<std::chrono::duration<Rep, Period>> duration)
{
    using date::operator<<;
    if (duration)
        std::cout << *duration << "\n";
    else
        std::cout << "none\n";
}

template <class Rep, class Period>
void foo(std::chrono::duration<Rep, Period> duration)
{
    foo(boost::optional<std::chrono::duration<Rep, Period>>{duration});
}

void foo(boost::none_t)
{
    foo(boost::optional<std::chrono::seconds>{});
}

int
main()
{
    using namespace std::chrono;
    foo(10ms);
    foo(10s);
    foo(boost::none);
}

以上,我还使用Howard's date lib来简化任意持续时间的打印:

10ms
10s
none