在下面的示例中,使用std :: chrono库,我正在寻找一种方法来接受基本计时器的持续时间类型。
template <std::chrono::duration D> //Accept either std::chrono::minute, second, etc...
class myTimer{
}
但是,由于持续时间与模板关键字的条件不匹配,因此无效。
template <class T>
class myTimer{
//I could do a static cast, but Duration is only a template used by the children, not an actual class per say.
}
所以我的问题归结为,对于更少的代码和更好的可用性,最佳解决方案是什么?我觉得像模板中一个不知名的孩子的静态演员阵容不会很好,但我可能完全错了。
答案 0 :(得分:0)
你在这里有很多选择,从简单而不是非常灵活,到非常灵活但更多的工作。
最简单的方法是只存储nanoseconds
,而不是模板myTimer
:
class myTimer
{
std::chrono::nanoseconds time_;
...
};
您的构造函数可以使用nanoseconds
。所有“内置”计时单元都将隐式转换为nanoseconds
:
myTimer t{3min}; // ok, 180'000'000'000ns
此处唯一的缺点是,每个 duration
都不会隐式转换为nanoseconds
。也许你希望你的客户能够使用皮秒,1 / 60s单位或浮点持续时间,或者这里的意图(很难说)是控制计时器内存储的精度(不是真的必要,但你永远不知道)。 然后您可能会转向模板化解决方案:
从is_duration
模板开始并不是一个糟糕的起点。即使你最终没有将它用于这个项目,它也可能在另一个项目中得心应用:
template <class T>
struct is_duration
: public std::false_type
{};
template <class Rep, class Period>
struct is_duration<std::chrono::duration<Rep, Period>>
: public std::true_type
{};
现在你可以说is_duration<T>{}
这是一个编译时bool,它将回答true为false。您可以像这样使用它(例如):
template <class D,
class = std::enable_if_t<is_duration<D>{}>>
class myTimer
{
D time_;
};
除了std::chrono::duration
之外,这将使实例化无法编译。
您也可以采用不需要is_duration
的方法:
template <class D> class myTimer;
template <class Rep, class Period>
class myTimer<std::chrono::duration<Rep, Period>>
{
};
如果有兴趣探索此路线,请尝试两种方式并确定您最喜欢的错误消息。
不要忘记:对您来说最好的解决方案可能是最简单的方法:只需使用nanoseconds
并使其具体化。