Как получить проверку ошибок времени компиляции с аргументами из реальных функций? - PullRequest
0 голосов
/ 20 декабря 2018

Возможно ли использовать static_assert (или что-то подобное) с аргументами функций, которые имеют реальную ценность?Я пытаюсь сделать следующее.Аргументы min и max всегда будут постоянными в моем приложении.В идеале я хотел бы использовать их в качестве параметров шаблона, но сделать это невозможно, потому что они реально ценятся.Мотивация для использования static_assert заключается в том, что я хотел бы получить проверку ошибок времени компиляции.

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);

1 Ответ

0 голосов
/ 20 декабря 2018

Хотя float s нельзя использовать в качестве параметров шаблона, float const& s можно.Таким образом, вы можете передать min и max в качестве параметров шаблона:

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);
}

Использование:

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

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

Изменение max на 5.0 приводит к необходимой диагностике:

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

Демо


В C ++ 17 вы можете избежать необходимости указывать тип min и 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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...