【问题标题】:How can I use std::chrono::duration as a template parameter?如何使用 std::chrono::duration 作为模板参数?
【发布时间】:2015-03-05 10:40:19
【问题描述】:

我有一个模板类,类似于:

template < typename T, size_t Seconds > class MyClass {}

现在,我想将 Seconds 更改为持续时间,因此可以使用 std::chrono::duration 对类进行参数化。例如,我希望能够做到这一点:

MyClass < std::string, std::chrono::seconds(30) > object;

另外,在模板中,我想指定一个默认值,例如std::chrono::seconds(30)

【问题讨论】:

  • 你应该考虑接受下面的答案,它看起来是一个可靠的答案。

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


【解决方案1】:

您可以巧妙地设计您的模板:

template < typename T, typename Duration = std::chrono::seconds, int duration_value = 30 > 
class MyClass 
{
    // Now you can use duration here:
    // auto duration = Duration(duration_value);
};

然后你可以将你的模板实例化为

MyClass < std::string, std::chrono::seconds, 30 > object;

或者,实际上将这些值作为默认值,只是

MyClass < std::string > object;

编辑:

考虑到PaperBirdMaster的要求,您可以将模板的Duration类型限制为仅限std::chrono::duration,这样:

template <typename T>
struct is_chrono_duration
{
    static constexpr bool value = false;
};

template <typename Rep, typename Period>
struct is_chrono_duration<std::chrono::duration<Rep, Period>>
{
    static constexpr bool value = true;
};

template < typename T, typename Duration = std::chrono::seconds, int duration_value = 30 >
class MyClass
{
    static_assert(is_chrono_duration<Duration>::value, "duration must be a std::chrono::duration");
    // Now you can use duration here:
    // auto duration = Duration(duration_value);
};

int main(int argc, char ** argv)
{
    MyClass < std::string, std::chrono::seconds, 1> obj1;       // Ok
    MyClass < std::string, std::chrono::milliseconds, 1> obj2;  // Ok
    MyClass < std::string, int, 1> obj3;                        // Error
    return 0;
}

【讨论】:

  • 这允许使用任何不是计时值的东西来实例化MyClass,例如:MyClass&lt;float, double&gt;,这是预期的行为吗?将第二个参数限制为 chrono 类型不是更好吗?
  • @PaperBirdMaster 您的逻辑也可以应用于例如std::remove_if。如果有人指定了一些意想不到的东西而不是UnaryPredicate p if 而不是迭代器怎么办?答案很简单:它不会编译。
  • 我们不知道MyClass 内部的逻辑,也许它会使用doublemy_fancy_class 进行编译,或者使用适当的运算符进行编译,这可能不是预期的行为......无论如何,问题是关于使用std::chrono::duration 对类进行参数化,而不是使用任何行为或类似于std::chrono::duration 的东西。
  • @PaperBirdMaster 然后写一个is_duration trait 并做一个static_assert。这很简单。
  • @PaperBirdMaster,是的,这就是概念出现的原因。我的观点是:目前,即使是标准库也没有设置任何约束。这是一种模板精神。如果我想设计自己的 std::chrono::duration 类似物并将其用作模板参数怎么办?
猜你喜欢
  • 2016-07-20
  • 1970-01-01
  • 2018-02-03
  • 2013-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-11
相关资源
最近更新 更多