【问题标题】:What is the C++11 equivalent to boost::date_time::not_a_date_time?什么是 C++11 等价于 boost::date_time::not_a_date_time?
【发布时间】:2014-11-10 21:29:33
【问题描述】:

我正在修改一个旧项目,同时我正在更新一些内容以将其升级到 C++11。

我想用 std::chrono 中的新功能替换 boost::date_time 的各种用途。但我无法弄清楚 boost::date_time::not_a_date_time 的 C++11 等价物是什么。

在 C++11 中是否有一个等价物表示尚未分配 time_point 变量,或者不包含有效的时间戳?

【问题讨论】:

  • 我有点困惑:你如何创建一个“无效”std::chrono::time_pointconstructors 似乎只允许创建“有效”时间点。
  • @dyp 这正是我遇到的问题。我无法弄清楚如何使用 std::chrono 来做到这一点。在 Boost::date_time——我想替换的库中——构造函数可以采用“特殊值”的枚举,其中之一是 boost::date_time::not_a_date_time。 boost.org/doc/libs/1_56_0/doc/html/date_time/…
  • 啊,我想我开始明白这个问题了。 std::chronoboost::chrono 相关,据我所知与 boost::date_time 无关。
  • 有一个构造函数接受一个枚举。例如:ptime(special_values sv) Constructor for infinities, not-a-date-time, max_date_time, and min_date_time 来自boost.org/doc/libs/1_56_0/doc/html/date_time/…
  • 正确,date_time 和 chrono 决一胜负,chrono 获胜并进入了 C++11。但是现在一些使用 date_time 的旧项目需要转换为 chrono。问题是 chrono 只包含 date_time 功能的一小部分。

标签: c++ c++11 chrono boost-date-time


【解决方案1】:

鉴于它作为一个组的一部分存在

bool is_infinity() const
bool is_neg_infinity() const
bool is_pos_infinity() const
bool is_not_a_date_time() const

很明显,这是通过使用浮点类型作为内部表示并将值设置为 NaN(非数字)来完成的。

std::chrono 中,表示类型必须是算术类型。因此,浮点类型符合条件,您可以使用相同的技巧。

给定一个std::duration,然后您可以使用它进行测试

std::isnan(dur.count())

(当然,您应该使用安静的 NaN 值,而不是信号 NaN,这样就不会触发浮点陷阱)

【讨论】:

  • 我不得不承认:我不明白这个答案。 not_a_date_time 的枚举是浮点类型如何清楚地表明这是真的(boost.org/doc/libs/1_56_0/doc/html/date_time/…)这如何帮助我在 std::chrono 中实现相同的功能?
  • @Stéphane:boost::date_time 的特殊值与 IEEE 浮点类型的特殊值完全对应。 std::chrono 中的所有类型都在算术类型和单位上进行了参数化(通过std::chrono::duration)。该算术类型可以是floatdouble
  • 另外,repchrono::duration 可以是模拟算术类型的类类型。因此,可以创建一个基于整数的Number 类,为NaN 保留其值之一(例如LLONG_MIN),并相应地实现其算术。
  • 好的,让我澄清一下:你说的是“很清楚这是使用浮点类型完成的”。这绝对是不正确的,因为boost::date_time 不使用浮点类型。当然,您是正确的,原则上您可以对std::chrono 类型使用浮点表示,但这是一种技巧;从语义上讲,chrono 类型没有“非日期时间”的概念。它玩得不好;转换回整数实际上是UB
  • 铸造案例只是一个例子。我的意思是duration_casting 是具有整数表示的计时类型。更重要的是,由于 chrono 类型没有非日期时间的概念,因此您不能指望任何使用这些类型的软件通过手动创建的 NaN 浮点值来做任何有用的事情。换句话说,在 std::duration 中使用浮点 NaN 是一个等待发生的意外,因为 除了 OP 自己编写的软件之外,没有任何软件可以以任何有意义的方式处理这个问题方式。
【解决方案2】:

boost::date_time 内部使用整数时间表示,并在boost/date_time/int_adapter.hpp 内部定义特殊值:

static const int_adapter  pos_infinity()
{
  return (::std::numeric_limits<int_type>::max)();
}
static const int_adapter  neg_infinity()
{
  return (::std::numeric_limits<int_type>::min)();
}
static const int_adapter  not_a_number()
{
  return (::std::numeric_limits<int_type>::max)()-1;
}
static  int_adapter max BOOST_PREVENT_MACRO_SUBSTITUTION ()
{
  return (::std::numeric_limits<int_type>::max)()-2;
}
static  int_adapter min BOOST_PREVENT_MACRO_SUBSTITUTION ()
{
  return (::std::numeric_limits<int_type>::min)()+1;
}

本质上,它保留了某些具有特殊含义的整数值。

但是,正如其他人指出的那样,std::chrono 不提供这些特殊值(只有min and max functions);并且std::numeric_limits 也不是专门的(请参阅Why does std::numeric_limits<seconds>::max() return 0?)。

Ben Voigt's answer 提供了一种可能的解决方法,但请注意,由于 std::chrono 类未指定此类语义,因此将 NaN 时间戳或持续时间传递给您不是自己编写的任何函数可能会触发未定义的行为。

【讨论】:

    猜你喜欢
    • 2017-09-05
    • 1970-01-01
    • 2016-11-29
    • 1970-01-01
    • 1970-01-01
    • 2020-01-09
    • 2014-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多