在泛型函数中接受 pointer/iterator

Accept pointer/iterator in generic function

我需要创建一个通用函数,它将分配一个与主函数中的 vector 具有相同元素的数组。

这个通用函数应该接受 pointers/iterators 到向量的开头和结尾。

#include <iostream>
#include <new>
#include <vector>
template <typename type> 
type *MakeArray(type::iterator start, type::iterator after_end) {
  int n = 0;
  while (start < after_end) {
    start++;
    n++;
  }
  start -= n;
  type *arr = nullptr;
  arr = new type[n];
  throw std::bad_alloc("Not enough memory!");
  while (start < after_end) {
    *arr = *start;
    start++;
    arr++;
  }
  delete[] arr;
  arr-=n;
  return arr;
}

int main() {
  int n=5;
  std::vector<double>a{1,2,3,4,5};
  double *arr = nullptr;
  try {
    arr = MakeArray(a.begin(),a.end());
  } catch (std::bad_alloc e) {
    std::cout << "Exception: " << e.what();
  }
  delete[] arr;

  return 0;
}

错误:

第 5 行:

expected ‘)’ before ‘after_end’

expected ‘;’ before ‘{’ token

第 30 行:

missing template arguments before ‘(’ token

我看不出有任何理由会出现这些错误。你能帮我修复我的代码吗?迭代器和动态分配对我来说是新的。

您可以使用迭代器类型本身作为模板参数,然后提取函数中包含元素的基础类型。

此外,您不应该在函数中使用 delete[] arr;,因为:(a) 此时,它不再指向由 new 调用分配的内存; (b) 如果这样做,您将无法在调用模块中使用它。

您还可以对函数进行其他一些重要的简化和改进,我在下面的代码中展示了这些:

template <typename it_type>
auto* MakeArray(it_type start, it_type after_end)
{
    using basetype = typename std::decay< decltype(*start) >::type; // Type of contained objects
    size_t size = static_cast<size_t>(std::distance(start, after_end)); // Quick calculation of size
    basetype* arr = new basetype[size]; // This will automatically throw (bad_alloc) if it fails
    std::copy(start, after_end, arr); // Quicker/easier way to do the data copy
    return arr;
}