Search code examples
c++guideline-support-library

How to eliminate 'Only index into arrays using constant expressions' warning?


I've written a kd-tree template, it's parameter being a natural number K.

As part of the template, I've written the following function to compute the distance between two points (kd_point is an alias for std::array)

template <unsigned K>
float kd_tree<K>::DistanceSq(const kd_point &P, const kd_point &Q)
{
    float Sum = 0;

    for (unsigned i = 0; i < K; i++)
        Sum += (P[i] - Q[i]) * (P[i] - Q[i]);

    return Sum;
}

I've turned "Enable C++ Core Check (Release)" on, and it gives me said warning. Is there a right way to write this routine to eliminate the warning?


Solution

  • Since you mention in comments that your kd_point's support range based iteration (so I assume can return iterators), you can re-write the function without the raw loop. Use named algorithms from the standard library instead:

    template <unsigned K>
    float kd_tree<K>::DistanceSq(const kd_point &P, const kd_point &Q)
    {
      return std::inner_product(
        begin(P), end(P), begin(Q), 0.0f, std::plus<float>{},
        [](float pi, float qi) {
          return (pi - qi)*(pi - qi);
        }
      );
    }
    

    The standard library would be exempt from the warning, of course. If the (in this case) marginal benefit of replacing a raw loop by a named operation doesn't appeal to you, consider that if you ever come back to this code with a C++17 enabled compiler, you'll be able to almost effortlessly parallelize it:

    template <unsigned K>
    float kd_tree<K>::DistanceSq(const kd_point &P, const kd_point &Q)
    {
      return std::transform_reduce(std::execution::par, // Parallel execution enabled 
        begin(P), end(P), begin(Q), 0.0f, std::plus<float>{},
        [](float pi, float qi) {
          return (pi - qi)*(pi - qi);
        }
      );
    }