Я не уверен, возможно ли это, но я открыт для идей.

У меня есть функция C ++. Он выполняет некоторые вычисления для массивов, которые определяются пользователями как входные, и генерирует два выходных значения. Назовем это «myfunction», и это будет выглядеть примерно так:

void myfunction (double array1 [18], double array [9], double array [2], double * output1, double * output2);

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

Например,

void myfunction (двойной массив1 [81], двойной массив [27], двойной массив [3], двойной * output1, double * output2)

Математически myfunction может рассчитывать точные результаты, несмотря на размер массива. Я не хочу делать дубликат «myfunction», потому что существует всего 5 различных наборов размеров массива, которые пользователь может определить в качестве входных данных.

Любые идеи? заранее спасибо

4
umz 14 Сен 2018 в 04:22

2 ответа

Лучший ответ

Вы можете передать std::vector или использовать template:

template <std::size_t N1, std::size_t N2, std::size_t N3> // and so on...
void work_with_arrays(double (&arr1)[N1], double (&arr2)[N2], double (&arr3)[N3]){
    std::cout << "First arr of a size: " << N1 << "\n";
    std::cout << "Second arr of a size: " << N2 << "\n";
    std::cout << "Third arr of a size: " << N3 << "\n";
};

int main() {
    double something[32];
    double fewer[13];
    double maybe_byte[8];

    work_with_arrays(something, fewer, maybe_byte);
}

Код выводит:

First arr of a size: 32
Second arr of a size: 13
Third arr of a size: 8

< Сильный > Объяснение :

Следует знать, что аргумент типа T[] (T - любой тип) распадается на T*. Если мы имеем дело с указателем на массив, у нас нет информации о его длине, что весьма прискорбно, учитывая тот факт, что длины массивов фиксированной длины известны во время компиляции и могут быть видны везде, где мы с ними работаем.

Также следует знать, что шаблон функции не функцией. Это шаблон, используемый для создания функций. Для каждого другого набора N#, использованного в приведенном выше примере, будет создана функция для нашего использования.

Как можно решить эту постоянно возникающую проблему?

Вместо передачи необработанного T[] мы должны передать ссылку на T[]. Таким образом, тип не распадается и размер массива будет известен.

< Сильный > Синтаксис

Можно было заметить, что T (&name)[some_size] выглядит как минимум странно. Скобки являются обязательными, так как простой T &name[size] будет интерпретироваться как T& name[size], который является массивом ссылок , а не ссылкой на массив .

< Сильный > Вывод:

Имея возможность определять размер массива, переданного в качестве аргумента, мы не хотим ограничиваться одним или двумя случаями - мы хотим охватить их все , поэтому мы используем {{X0 }} для генерации функций с N# необходимого значения.

8
Fureeish 14 Сен 2018 в 10:03

Вы можете использовать в своей функции vector, который является «массивом с динамически изменяемым размером». Вы можете перебирать его или получать размер по мере необходимости. См. Его документы.

#include <vector>
using std::vector;  // I'm too lazy to prepend std:: as needed.
void myfunction(const vector<double>& array1, 
                const vector<double>& array2,
                const vector<double>& array3, 
                vector<double>& output1, vector<double>& output2) {

}

Если это невозможно, попросите его принять дополнительные аргументы, указывающие размер массивов.

void myfunction(double *array1,
                double *array2, 
                double *array3,
                int size1,
                int size2,
                int size3,
                double *output1, 
                double *output2) {

}

Но это действительно некрасиво. Просто выберите первый вариант.

3
lightalchemist 14 Сен 2018 в 01:32