I'm not sure if this is possible but i'm open to ideas.
I have a c++ function. It does some calculation to arrays that are being defined by users as inputs and will generate two output values. Let's call it "myfunction" and it looks something like this:
void myfunction(double array1[18],double array[9],double array [2],double *output1, double *output2)
I want to make this function more generic so that it is able to take in arrays of different size. Meaning, I want users of this function to be able to define array inputs of other size.
For example,
void myfunction(double array1[81],double array[27],double array [3],double *output1, double *output2)
Mathematically, "myfunction" is able to calculate accurate outputs despite the array size. I don't want to make a duplicate of "myfunction" because there are a total of 5 different sets of array size that the user can define as inputs.
Any ideas? thank you in advance
You can either pass a std::vector
or use a 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);
}
The code outputs:
First arr of a size: 32
Second arr of a size: 13
Third arr of a size: 8
Explanation:
One should know that the argument of type T[]
(T
being any type) decays to T*
. If we're dealing with a pointer to an array, we have no information about its length, which is quite unfortunate, given the fact that lengths of fixed-length arrays are known at compile time and could be visible everywhere we work with them.
One should also know that a function template is not a function. It is a template used to create functions. For every different set of N#
used in the example above, there will be a function generated for our use.
What is the workaround to the decaying problem?
Instead of passing a raw T[]
, we should pass a reference to T[]
. That way the type does not decay and the size of the array will be known.
Syntax?
One could notice that T (&name)[some_size]
looks at least bizarre. The parentheses are required, since plain T &name[size]
would be interpreted as T& name[size]
, which is an array of references, not a reference to an array.
Conclusion:
Being able to detect the size of a passed-as-argument array, we don't want to limit ourselves with one or two cases - we want to cover them all, so we use a template
to generate functions with N#
of needed value.
You can have your function take in a vector
which is a "dynamically resizable array". You can iterate over it, or get its size as needed. See its docs.
#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) {
}
If that is not possible, then have it take in extra arguments indicating the size of the arrays.
void myfunction(double *array1,
double *array2,
double *array3,
int size1,
int size2,
int size3,
double *output1,
double *output2) {
}
but this is really ugly. Just go with the first option.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With