Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get compile time error checking with real valued function arguments?

Tags:

c++

c++11

Is it possible use static_assert (or something similar) with function arguments that are real valued? What I am trying to do is the following. The arguments min and max will always be constant in my application. Ideally, I would like to use them as template parameters, but doing so isn't possible because they are real valued. The motivation for using static_assert is that I would like to get compile time error checking.

template <typename counts_t, typename real_t>
real_t counts2real(counts_t c, real_t min, real_t max)
{
  constexpr real_t cmin = std::numeric_limits<counts_t>::min();
  constexpr real_t cmax = std::numeric_limits<counts_t>::max();
  constexpr real_t cdelta = (cmax - cmin);

  // ERROR: non-constant condition for static assertion.
  static_assert(max > min, "max > min");

  real_t delta = (max - min);
  real_t p = (c - cmin) / cdelta;

  return (p * delta + min);
}

int16_t x = 0;
const float min = 10.0;
const float max = 5.0;

float xf = counts2real<int16_t,float>(x, min, max);
like image 394
fuse117 Avatar asked May 20 '26 07:05

fuse117


1 Answers

While floats cannot be used as template parameters, float const&s can. Thus, you can pass min and max as template parameters:

template <typename real_t, real_t const& min, real_t const& max, typename counts_t>
real_t counts2real(counts_t c)
{
  constexpr real_t cmin = std::numeric_limits<counts_t>::min();
  constexpr real_t cmax = std::numeric_limits<counts_t>::max();
  constexpr real_t cdelta = (cmax - cmin);

  static_assert(max > min, "max > min");

  real_t delta = (max - min);
  real_t p = (c - cmin) / cdelta;

  return (p * delta + min);
}

Usage:

constexpr float min = 10.0;
constexpr float max = 50.0;

float foo(int16_t x) {
    return counts2real<float, min, max>(x);
}

Changing max to 5.0 results in a diagnostic as desired:

<source>:13:21: error: static assertion failed: max > min
   static_assert(max > min, "max > min");

Demo


In C++17, you can avoid having to specify the type of min and max:

template <auto const& min, auto const& max, typename counts_t>
constexpr auto counts2real(counts_t c)
{
  ...
}

// ...
float foo(int16_t x) {
    return counts2real<min, max>(x);
}
like image 184
Justin Avatar answered May 21 '26 20:05

Justin



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!