【问题标题】:Reducing casting clutter in C++减少 C++ 中的转换混乱
【发布时间】:2012-03-20 12:43:15
【问题描述】:

在编写泛型类时,我的方法最终会被强制转换弄得杂乱无章(否则我会收到警告,这在我们的项目中被视为错误):

template <typename floatType>
class foo
{
public:
  typedef floatType real_type;

  real_type bar()
  {
    real_type a = (real_type)0.5; // should I be using static_cast? Either way, the code becomes cluttered quickly
    real_type b = a + 0.6; // warning here for floatType = float

    real_type someLongEquation = a + ((real_type)0.5 * (real_type)100) + (real_type)17.0;

    return a + b + someLongEquation;
  }
};

int main()
{
  {
    foo<float> z;
    z.bar();
  }

  {
    foo<double> z;
    z.bar();
  }

  return 0;
}

有什么办法可以减少这种混乱吗?

请注意,我意识到我在 someLongEquation 中使用了魔术常量。即使我将它们分开,也会增加混乱。无论哪种方式,这都不是问题的重点:)

【问题讨论】:

  • 您收到什么警告?
  • @DavidBrown: Conversion from 'double' to 'float', possible loss of data(内置类型之间的强制转换非常标准,可能会导致精度损失)
  • 只需在每个常量值后面加上f。将 float 分配给 double 是可以的;)
  • @Rob:MSVC(如果您一直在使用 MSVC,警告会泄露这一点)。

标签: c++ templates casting


【解决方案1】:

一种简单的方法是关闭代码周围的警告。使用 MSVC:

#pragma warning(push) // save warnings state
#pragma warning(disable:4244) // narrowing conversion
// code here ...
#pragma warning(pop) // restore warnings

但是,如果您的魔术常量不需要 double 的扩展精度,更好的方法是只使用 float 文字。只需将 f 附加到您的浮点文字,就可以了。此外,100 不需要演员表。如果您确实需要精确度,那么,请回退到禁用警告。

【讨论】:

    【解决方案2】:

    您应该将魔术常量分开并将它们存储在正确的泛型类型中。所有的演员都将被限制在那个位置。现在(我认为)C++11 允许在类中初始化非整数 const 静态变量,这很容易。

    template <typename floatType>
    class foo
    {
    public:
      typedef floatType real_type;
    
      static constexpr real_type A = real_type(0.5);
      static constexpr real_type B = real_type(0.6);
      static constexpr real_type C = real_type(100.0);
      static constexpr real_type D = real_type(17.0);
    
      real_type bar()
      {
        real_type a = A;
        real_type b = a + B;
    
        real_type someLongEquation = a + (A * C) + D;
    
        return a + b + someLongEquation;
      }
    };
    

    【讨论】:

    • IIRC,C++11 只允许非静态成员使用。
    • @Xeo 我以前找不到参考资料,但现在我找到了。如果静态 constexpr 数据成员具有“文字类型”(包括float),则可以在类中对其进行初始化。 [class.static.data] §9.4.2/3
    • 啊,是的,我不知何故忽略了constexpr。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-27
    • 1970-01-01
    • 2014-07-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多