将二进制操作员应用于数组中的每个元素

Apply a binary operator to each element in an array

本文关键字:元素 数组 二进制 操作员 应用于      更新时间:2023-10-16

给定一个二进制函数(或类似函子(对象,该对象采用两个类型的T*和一个大小并返回T*,这是将该函数应用于每个对象的规范方法数组,返回新的?

,即等同的东西,但比以下几点较短且较小的错误:

template<typename T, typename O>
T* apply(const T* a1, const T* a2, size_t size, O op) {
  T* out = new[size];
  for (size_t i = 0; i < size; i++) {
    out[i] = op(a1[i], a2[i]);
  }
  return out;
}

我对输出的分配方式的细节不太大。在上面的示例中,它分配在堆上,但也许其他变体覆盖了其中一个输入或写入提供的缓冲区,或者也许是使用std::array<>并返回,等等。

您提到使用数组的工作C风格的C风格阵列参数。

如果适用(呼叫站点的限制(,则可以使用std::array来避免尺寸信息的丢失,同时仍在编写一个尺寸 - 敏捷的功能模板,并以两个数组参数都相同的约束大小(当您执行典型的拉链和地图操作时,我们可能会期望这(。

例如。使用 std::transform将二进制操作员应用于to数组参数中的配对元素:

#include <algorithm>
#include <array>
#include <iostream>
template <typename T, typename BinaryOperator, std::size_t N>
auto apply(const std::array<T, N>& arr1, const std::array<T, N>& arr2,
           const BinaryOperator& op) {
  std::array<T, N> result{};
  std::transform(arr1.begin(), arr1.end(), arr2.begin(), result.begin(), op);
  return result;
}
int main() {
  const std::array<int, 5> arr1 = {1, 2, 3, 4, 5};
  const std::array<int, 5> arr2 = {6, 7, 8, 9, 10};
  const auto results = apply(arr1, arr2, [](int i, int j) { return i + j; });
  for (const auto num : results) {
    std::cout << num << " ";
  }  // 7 9 11 13 15
}

或,如果您可以使用C 14,则std::integer_sequence与参数包扩展合并:

#include <array>
#include <iostream>
#include <utility>
namespace detail {
template <typename Array, typename BinaryOperator, std::size_t... I>
Array apply_impl(const Array& arr1, const Array& arr2, const BinaryOperator& op,
                 std::index_sequence<I...>) {
  return {op(arr1[I], arr2[I])...};
}
}
template <typename T, typename BinaryOperator, std::size_t N,
          typename Indices = std::make_index_sequence<N>>
auto apply(const std::array<T, N>& arr1, const std::array<T, N>& arr2,
           const BinaryOperator& op) {
  return detail::apply_impl(arr1, arr2, op, Indices{});
}
int main() {
  const std::array<int, 5> arr1 = {1, 2, 3, 4, 5};
  const std::array<int, 5> arr2 = {6, 7, 8, 9, 10};
  const auto results = apply(arr1, arr2, [](int i, int j) { return i + j; });
  for (const auto num : results) {
    std::cout << num << " ";
  }  // 7 9 11 13 15
}