Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compile time operations on floating point types

I have some static const floating point member variables, on which I want to do some compile time static asserts. The following code compiles in gcc but fails in both clang and 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;
}

I get errors in Visual Studio 2013 and Clang for the static assert statements complaing about constant expression:

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

A non c++11 solution for doing this will be highly appreciated. Also is there other ways to do these kind of checks on static parameters?

like image 687
iNFINITEi Avatar asked Mar 25 '26 13:03

iNFINITEi


1 Answers

As dyp stated in comment, floating-point type variables cannot be used in constant expression. A possible workaround would be to use rational number.

std::ratio is C++11 but can easily be ported to 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");
};
like image 118
Jarod42 Avatar answered Mar 27 '26 03:03

Jarod42



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!