【问题标题】:How to get the 0 of a numeric type in C++?如何在 C++ 中获取数字类型的 0?
【发布时间】:2014-09-12 20:30:41
【问题描述】:

在 C++ 中是否有标准的方法来获取数字类型的 0 和 1。这在编写使用以下类型模板化的线性代数例程时很有用:intdoubleunsigned int、...

我在想

static_cast<T>(0)

但我想知道是否没有更好的方法。

【问题讨论】:

  • 只使用01 怎么样?它们可以隐式转换为所有数字类型。
  • 约阿希姆:似乎是个好主意。我仍然害怕隐式转换,但既然他们在这里,应该使用它。

标签: c++


【解决方案1】:

通常只需 01 就可以了,让促销规则做正确的事。

如果您想确保它们被转换为预期的类型,请使用T(0)T(1)

(正如其他答案指出的那样,您可以从值初始化中获得零值,T()T{}。但是没有类似的方法可以得到 1;在我看来,一点点(稍微) 降低清晰度只是为了保存单个字符。)

【讨论】:

    【解决方案2】:

    在 C++11 中,我更喜欢使用 T {}。好消息是它适用于 any 默认可构造类型。

    【讨论】:

    • 问题在于 std::array 之类的东西没有使用默认构造函数初始化为 0。因此 T {};不会是 0。如果我考虑这些类型,我更愿意收到错误消息。
    • 默认构造函数应该将对象初始化为给定类型的“空”的适当定义。如果您的模板无法处理非数字类型,您可以使用std::enable_if 来强制执行此操作。
    • @InsideLoop:作为一个聚合,std::array 是零初始化的,如果你使用{}() 来指定值初始化。 (即使不是这样,它与数字类型有什么关系?)
    • Mike Seymour:std::array 不是数字类型。但是您可以轻松地在这些类型上定义 + 和 *,使其成为环(数学术语),因此,您可以使用它进行线性代数。所以对于“数学家”来说,它可以被认为是一种“数字类型”。
    • @InsideLoop:很公平。但无论如何,使用{}() 进行值初始化确实将数组的所有元素初始化为零。
    【解决方案3】:

    初始化为默认值的原生数据类型是initialized to zero

    int a = int(); // 0
    double b = double(); // 0.0
    T x = T(); // same as static_cast<T>(0) for T as a native type
    

    【讨论】:

      【解决方案4】:

      我会使用(T)0,这基本上是您已经使用的。如果您实现任何接近线性代数系统的东西,您可以考虑将所有类型的所需数字类型包装在一个一致的基类中,从而允许对字段、环等进行更结构化的表示。

      【讨论】:

      • C 风格的演员是你永远不应该使用的东西。
      • @Melkon:为什么不呢?如果涉及指针或引用类型,这是很危险的(您最终可能会得到一个不需要的 const/reinterpret_cast 给出无效结果而不是友好的编译时错误),但问题是关于数字转换。
      • 所以你说,你想避免 const 并重新解释演员表。好吧,在这种情况下,您显然也希望避免使用 dynamic_cast,因为它很昂贵,而且它可以是 nullptr。所以实际上你想使用static_cast。为什么不直接写呢?
      • @Melkon:我不明白你的意思;我为什么要避免 C 风格的演员表?
      • 因为 C 风格的强制转换意味着,你不知道自己在做什么。你不能肯定,你会得到你期望的结果,在很多情况下它是一个定时炸弹。就像你重构了一些早期的代码一样,一个 static_cast 神奇地变成了一个 reinterpret_cast 而没有任何通知。很难阅读,因为读者不知道会发生什么。 C++ 有 4 种类型的强制转换是有充分理由的。
      猜你喜欢
      • 1970-01-01
      • 2018-02-19
      • 1970-01-01
      • 2012-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-22
      • 2019-11-17
      相关资源
      最近更新 更多