编译浮点类型的时间操作

时间:2014-08-04 19:18:24

标签: c++ boost clang static-members static-assert

我有一些静态const浮点成员变量,我想在其上做一些编译时静态断言。以下代码在gcc中编译,但在clang和Visual Studio中都失败:

#include <boost/static_assert.hpp>
#include <iostream>

template<typename Scalar>
class ProbModel {
public:
  static const Scalar probA;
  static const Scalar probB;

private:
  BOOST_STATIC_ASSERT_MSG(probA < 1, "Weird Parameter");
  BOOST_STATIC_ASSERT_MSG(probB < 1, "Weird Parameter");
  BOOST_STATIC_ASSERT_MSG(probA < probB, "Weird Parameter");
};

// Initializations
template<typename Scalar> const Scalar
ProbModel<Scalar>::probA = 0.3;

template<typename Scalar> const Scalar
ProbModel<Scalar>::probB = 0.6;

int main(int argc, char* argv[]) {
  typedef ProbModel<float> Modelf;
  std::cout << "ProbA = " << Modelf::probA << std::endl;
}

我在Visual Studio 2013中遇到错误,而Clang因为静态断言语句而抱怨常量表达式:

2>..\static_assert_experiments.cpp(11): error C2057: expected constant expression
2>..\static_assert_experiments.cpp(12): error C2057: expected constant expression
2>..\static_assert_experiments.cpp(13): error C2057: expected constant expression

用于执行此操作的非c ++ 11解决方案将受到高度赞赏。还有其他方法可以对静态参数进行这些检查吗?

1 个答案:

答案 0 :(得分:1)

正如dyp在注释中所述,浮点类型变量不能用于常量表达式。可能的解决方法是使用有理数。

std::ratio是C ++ 11,但很容易移植到C ++ 03

template<typename Scalar>
class ProbModel {
public:

    static Scalar getProbA() { return Scalar(probA::num) / probA::den; }
    static Scalar getProbB() { return Scalar(probB::num) / probB::den; }

private:
    typedef std::ratio<3, 10> probA; // 0.3
    typedef std::ratio<6, 10> probB; // 0.6

    BOOST_STATIC_ASSERT_MSG(probA::num < probA::den, "Weird Parameter");
    BOOST_STATIC_ASSERT_MSG(probB::num < probB::den, "Weird Parameter");
    BOOST_STATIC_ASSERT_MSG(probA::num * probB::den < probB::num * probA::den, "Weird Parameter");
};