Я написал шаблон дерева kd, его параметром является натуральное число K.
Как часть шаблона, я написал следующую функцию для вычисления расстояния между двумя точками (kd_point — это псевдоним для 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;
}
Я включил «Включить проверку C ++ Core (Release)», и он предупреждает меня. Есть ли правильный способ написать эту процедуру, чтобы устранить предупреждение?
Поскольку вы упоминаете в комментариях, что ваш kd_point
Итерация, основанная на диапазоне поддержки (поэтому я предполагаю, что может возвращать итераторы), вы можете переписать функцию без необработанного цикла. Вместо этого используйте именованные алгоритмы из стандартной библиотеки:
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);
}
);
}
Конечно, стандартная библиотека будет освобождена от предупреждения. Если (в данном случае) предельное преимущество замены необработанного цикла на именованную операцию вам не подходит, учтите, что если вы когда-нибудь вернетесь к этому коду с компилятором с поддержкой C ++ 17, вы сможете почти без усилий распараллелить это:
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);
}
);
}
Ответ от рассказчик это, вероятно, самый подходящий способ C ++ для решения этой конкретной задачи.
Я хотел бы добавить, что в целом, если вы хотите выполнять итерации не по одной, а по двум последовательностям одновременно, вы можете использовать «секретную перегрузку boost::range::for_each
«, принимая два диапазона:
#include <boost/range/algorithm_ext/for_each.hpp>
template <unsigned K>
float kd_tree<K>::DistanceSq(const kd_point &P, const kd_point &Q)
{
float Sum = 0;
boost::range::for_each(P, Q, [&Sum](float p, float q)
{
Sum += (p - q) * (p - q);
});
return Sum;
}
Обратите внимание, что, как и в случае со стандартными алгоритмами, этот алгоритм предназначен только для заголовков и не вносит никакой зависимости от библиотеки в ваш код.