Передайте функцию double или vector<double>&

У меня есть функция, которая вычисляет первую производную dy/dx для дискретных значений y(x), построенных как std::vector:

vector<double> CalcDerivative(vector<double>&y, vector<double>&x) {...}

Часто интервал dx является постоянным, поэтому было бы эффективнее передать этой функции значение типа double вместо vector<double> в качестве аргумента x.

Я попытался сделать это с помощью std::variant. Однако недостатком std::variant является то, что он не может обрабатывать ссылки, поэтому вектор x должен быть скопирован при передаче в функцию как вариант.

На данный момент я решил проблему, определив две функции с перегруженными аргументами. Но мне интересно, есть ли более элегантное решение, которое не будет дублировать код для двух случаев (x как double или как vector<double>).

Лично я бы сказал, что перегрузка — это довольно элегантное (и, безусловно, читабельное) решение. Чтобы избежать дублирования кода, извлеките метод для общих частей (вы не предоставили код, поэтому я не могу быть более конкретным). Кроме того, в копировании данных нет ничего плохого. Не делайте преждевременных оптимизаций.

Friedrich 02.02.2023 09:28

Либо передайте значение 1 также как vector и проверьте if (x.size() == 1), либо сделайте аргумент x шаблоном, а затем проверьте if constexpr, это double всегда используйте это, а если нет, используйте индекс массива.

mch 02.02.2023 09:31

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

PaulMcKenzie 02.02.2023 09:50
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Одним из возможных решений может быть определение «рабочей» функции таким образом, чтобы она не зависела от «количества переданных двойников». Для этой цели подойдет std::span. Примерное решение может выглядеть так:

std::vector<double> CalcDWorker(
  std::span<const double> y, std::span<const double> x)
{
  ... // x.size() == 1 indicates uniform spacing
}

std::vector<double> CalcDerivative(
  const std::vector<double>& y, const std::vector<double>& x)
{
  return CaclDWorker({y.begin(), y.end()}, {x.begin(), x.end()});
}

std::vector<double> CalcDerivative(
  const std::vector<double>& y, double x)
{
  return CaclDWorker({y.begin(), y.end()}, {&x, 1});
}

Для этого требуется C++20, но есть сторонние span реализации, доступные и для более ранних версий C++ (например, предоставленная Boost).

Живая демонстрация: https://godbolt.org/z/n6adEKWes

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