3 votes

Comment obtenir un contrôle d'erreur au moment de la compilation avec des arguments de fonction à valeur réelle ?

Est-il possible d'utiliser static_assert (ou quelque chose de similaire) avec des arguments de fonction à valeur réelle ? Ce que j'essaie de faire est le suivant. Les arguments min y max sera toujours constante dans mon application. Idéalement, j'aimerais les utiliser comme paramètres de modèle, mais ce n'est pas possible parce qu'ils ont une valeur réelle. La motivation pour utiliser static_assert est que j'aimerais obtenir un contrôle d'erreur au moment de la compilation.

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

5voto

Quincunx Points 1923

Tandis que float ne peuvent pas être utilisés comme paramètres de modèle, float const& peuvent. Ainsi, vous pouvez passer min y max comme paramètres du modèle :

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

Utilisation :

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

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

Changer max à 5.0 Les résultats dans un diagnostic comme souhaité :

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

Démonstration


En C++17, vous pouvez éviter d'avoir à spécifier le type de min y 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);
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X