【问题标题】:C style casting and readability in C++C++ 中的 C 风格转换和可读性
【发布时间】:2010-12-09 15:10:33
【问题描述】:

是的,我知道你不应该在 C++ 中使用 C 风格强制转换,但在某些情况下,我真的认为如果你这样做会更具可读性,例如比较这两个:

d = ((double)i * 23.54) / (d + (double)j);

d = (static_cast<double>(i) * 23.54) / (d + static_cast<double>(j));

哪个更易读?

现在谈谈我的主要问题。显然我更喜欢上面的那个,但我认为有一种方法可以使它更具可读性:

d = (double(i) * 23.54) / (d + double(j));

我的问题是,这会降低效率吗?在这种情况下,编译器会比使用其他方法创建更多的双精度数,还是足够聪明地不这样做?这是否比典型的 C 风格转换更糟糕?

【问题讨论】:

  • 在 C++ 中使用 C++ 类型转换,并避免在 C++ 对象上使用 C 样式类型转换。不是重复但有点相关stackoverflow.com/questions/1635897/…
  • +1 好问题,我想我从来没有用过 double(i),我承认它的可读性很好。
  • static_cast<...> 更容易搜索。
  • 如果ijint 并且ddouble,则不需要任何上述转换。
  • 嗯,我明白了。但是假设它只是为了论证或可读性而需要的。我的例子很糟糕。

标签: c++ c casting readability


【解决方案1】:

它们都是不可读的。你应该写:

d = (i * 23.54) / (d + j);

【讨论】:

  • @DaedalusAlpha:实际上,没关系。 C++ 将为您进行转换并使用最合适的类型。此解决方案的一大优点是,如果您突然将d 更新为floatlong double 类型,那么编译器仍将执行最合适的转换,而您的显式转换将需要手动更改...有些可能会被遗忘。
  • @DaedalusAlpha:我已经为需要选择转换的情况添加了一个答案(例如,为了获得精度),简而言之,我强烈推荐boost::numeric_cast,因为它会检查溢出/下溢从而防止令人讨厌的未定义行为。
  • @DaedalusAlpha:它使用“只是为了安全”的转换,这往往会给人们带来 C 转换的麻烦:因为它们足够强大,可以执行 不是 安全,您可能会无意中创建一个表达式,当在别处更改类型时,它会默默地从“过于冗长但正确”变为“非常、可悲地错误”......
  • @j_random_hacker:你的例子很糟糕而且完全是错误的。如果RAND_MAXINT_MAX,那么RAND_MAX+1 在你转换为double 之前已经溢出。用1.0 替换1 将修复错误并删除无用的演员表。
  • @DaedalusAlpha:浮点类型总是胜过整数类型。 (如果您仔细阅读,我的评论实际上暗示了这一点。)所有二进制算术和关系(&lt;== 等)运算符都以相同的方式操作,转换“向上”小类型参数。算术运算符的结果类型是对它们进行任何转换后的操作数的常见类型。 % 的操作数和位运算符必须是整数。
【解决方案2】:

编译器将“创建”完全相同数量的双精度数。转换为和构造原始数字类型之间没有实际区别。

【讨论】:

  • 虽然我非常感谢其他答案和我在此线程中获得的信息,但这是唯一真正回答了我的具体问题的答案,所以我将其标记为答案 ;)
【解决方案3】:

在这种特殊情况下,我已经评论了 R 关于让编译器挑选演员表的答案。

但在某些情况下,您确实需要显式转换:

  • 您想防止溢出或提高精度
  • 您要检查转换的有效性

Boost Numeric Conversion 在这里提供了非常合适的演员阵容,比static_cast 好得多:boost::numeric_cast

  • 不需要检查时没有开销(即从小整数转换为大整数)
  • 在需要时对值进行运行时检查(即从大到小或有符号转换为无符号)

它比 static_cast 更具可读性,因为数字的本质被突出显示,并且更安全,因为它可以防止未定义的行为(和可移植性问题)出现。

【讨论】:

  • 您的版本,即使您修复了错误,仍然存在偏差。可能非常糟糕的偏差,取决于 n 的值。
  • @Matthieu:阅读我对他发布该示例的其他地方的评论。错了。
  • @Matthieu:可悲的是,sn-p 包含了我试图避免的 exact 溢出错误......再次出现,已更正:
  • 示例:要获取 0 - (n-1) 范围内的 int,请使用 (int) ((rand() / ((double) RAND_MAX + 1) * n)。在RAND_MAX 是最大可表示整数的许多系统上,(double) 对于避免整数溢出至关重要。 (为什么不只是rand() % n?这是有偏见的。)
  • @R.:您能否解释/指出对这种“非常糟糕的偏见”的解释?这对我来说是个新闻。
【解决方案4】:

C++ 中的强制转换函数长而笨重的原因是设计使然 1)为了向用户展示他可能做错了什么 2)在必要的情况下,请注意那段代码,它可能正在做一些危险或非常规的事情。

【讨论】:

    【解决方案5】:

    恕我直言,static_cast 更具可读性,因为它向读者提供了有关演员表性质的信息。

    【讨论】:

      猜你喜欢
      • 2013-05-16
      • 2016-12-17
      • 2010-12-09
      • 1970-01-01
      • 2017-02-03
      • 2020-08-28
      • 1970-01-01
      • 2011-06-13
      相关资源
      最近更新 更多