Принять указатель/итератор в универсальной функции

Мне нужно создать общую функцию, которая будет выделять массив, содержащий те же элементы, что и вектор в основной функции.

Эта общая функция должна принимать указатели/итераторы на начало и конец вектора.

#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

Я не вижу причин, почему я должен получать эти ошибки. Не могли бы вы помочь мне исправить мой код? Итераторы и динамическое размещение для меня новы.

Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
2
0
66
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете использовать сам тип итератора в качестве аргументов шаблона, а затем извлечь базовый тип содержащихся в функции элементов.

Кроме того, вы не должны использовать delete[] arr; в своей функции, потому что: (а) в этот момент она больше не указывает на память, выделенную вызовом 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;
}

Конечно, если вы хотите скопировать только весь вектор, вы можете просто передать сам этот вектор (по ссылке) и использовать члены .begin() и .size(). Но показанный код должен работать для любого диапазона/поддиапазона вектора (или даже другого типа контейнера) с учетом соответствующих итераторов.

Adrian Mole 09.04.2022 15:09

большое спасибо, не могли бы вы отредактировать свой код для пользовательского сообщения bad_alloc? Мне нужно установить пользовательское сообщение для bad_alloc, но когда я пытаюсь добавить пользовательское сообщение, я получаю сообщение об ошибке no matching function for call to ‘std::bad_alloc

codproe 09.04.2022 15:14

@codproe Вы можете сделать это в блоке try ... catch (const std::bad_alloc& e) в своей вызывающей (main) функции. Пример на cppreference. Или вы можете поместить это в MakeArray, а затем return nullptr; в конце catch.

Adrian Mole 09.04.2022 15:19

Другие вопросы по теме