This question already has answers here:
Why does argument matching in C++ ignore array sizes?
(1 answer)
In a function declaration, what does passing a fixed size array signify? [duplicate]
(3 answers)
Why can one specify the size of an array in a function parameter?
(3 answers)
Closed 3 years ago.
In C++, arrays are supposed to be passed to functions by reference. Hence, in what follows, function foo should implicitly use array inp by reference.
void foo(double inp[10]) {}
void foo1(double (&inp)[10]) {}
My question is, since both functions supposedly have the same interpretation of the input variable, why can we call foo in what follows, but we cannot call foo1?
int main()
{
double ary[20];
foo(ary); // compiles without any problem.
foo1(ary); // compiler error: invalid initialization of reference of type ‘double (&)[10]’ from expression of type ‘double [20]’
return 0;
}
since both functions supposedly have the same interpretation of the input variable
But they don't. A function argument of the type double inp[10] is automatically adjusted to a pointer double*. The 10 plays no part in providing type information here. Since all arrays decay to pointers, that will allow you to pass an array of any size.
A reference to an array does not get adjusted however. The type information is still there, and it must be a reference to an array of exactly ten doubles. The only way to pass a reference to an array of any size is to have a separate function for it, which you may write a function template to accomplish
template<std::size_t N>
void foo2(double (&inp)[N]) {}
Related
This question already has answers here:
Passing an array as a parameter in C
(3 answers)
Passing Arrays to Function in C++
(5 answers)
Closed 8 months ago.
I am passing a fixed size array to a function (the size is defined to a constant in the function's definition). However, I still get the error
No matching function for call to 'begin'
# define arr_size 2
void test(int arr0[2]){
int arr1[]={1,2,3};
int arr2[arr_size];
begin(arr0); // does not work -- how can I make this work?
begin(arr1); // works
begin(arr2); // works
}
There is a related discussion here, however, the array's size was clearly not constant in that case. I want to avoid using vectors (as suggested there) for efficiency reasons.
Does anyone know what the issues is?
This function declaration
void test(int arr0[2]){
is equivalent to
void test(int *arr0){
because the compiler adjusts parameters having array types to pointers to array element types.
That is the both declarations declare the same one function.
You may even write for example
void test(int arr0[2]);
void test(int *arr0){
//,,,
}
So you are trying to call the function begin for a pointer
begin(arr0);
You could declare the parameter as a reference to the array type
void test(int ( &arr0 )[2]){
to suppress the implicit conversion from an array to a pointer.
This question already has an answer here:
Is int arr[ ] valid C++?
(1 answer)
Closed 10 months ago.
I'm reading some materials about C++ and I just saw that array can be declared without a size (ex. int arr[], char x[][10]) and I'm wondering how/when it's actually used. Could someone explain both examples, please?
A more explicit example:
void foo(char[][10]);
Does that mean that any array like a[n][10], a[m][10] can be passed to the above function?
Does that mean that any array like a[n][10], a[m][10] can be passed to the above function?
Yes. The function signature void foo(char[][10]); is allowed as long as you pass a compatible argument, i.e. a char array with 2 dimensions in which the second has size 10.
In fact, technically, the argument will decay to a pointer, so it's the same as having void foo(char (*)[10]);, a pointer to array of ten, in this case chars. An argument of type char[] will also decay, this time to a pointer to char (char*).
Furthermore omitting the first dimension of an array is permitted on declaration as long as you initialize it. The fist dimension of the array will be deduced by the compiler based on the initialization content, i.e.:
int arr[]{1,2};
will have size 2 (arr[2]) whereas
int arr[][2]{{1,2},{2,4}};
will become arr[2][2] based on the aggregate initialization.
This question already has answers here:
passing an array as a const argument of a method in C++
(5 answers)
Closed 4 years ago.
I'm trying to initialize a dynamic array and pass it through a function, but I keep getting errors every-time I do so.
float addLayer(float layers[]){
float addColor = 0;
if (std::find(std::begin(layers), std::end(layers), addColor)){
// run code
addColor = ...;
}
return addColor
}
float layers[] = {0};
newColor = addLayer(layers[]); //line 2
Error I receive:
Expected identifier or '(' on line 2
Any help would be appreciated, thank you
float addLayer(float layers[]);
is equivalent to
float addLayer(float* layers);
i. e. all you have is the pointer. All length information is lost as soon as the array decays to the pointer.
To retain length information, you can pass it in a separate parameter, alternatively, you can pass a reference to array:
template <size_t N>
float addLayer(float(&layers)[N]); // pass reference to array of length N
Additionally, there's a syntax error:
newColor = addLayer(layers[]);
// ^^
Layers is already an array (but decays to pointer if passed to pointer version of function), and what you actually do in above line is applying the index operator to the array – however without argument (note that with argument, you'd get a float value, not a pointer any more).
Finally: Both std::array(fixed size) and std::vector(variable size) are better alternatives to raw arrays, prefer using one of these whenever possible.
The problem is you can't pass a C array as an argument to a function -- C does not allow it, so C++ does not either. If you declare a function as taking a C array as a parameter, the compiler silently changes it into a pointer, so you're actually passing a pointer. Thus, calling std::begin and std::end on that pointer argument won't work.
In order to make this work in C++, you need to use a std::array or std::vector instead.
This question already has answers here:
Passing references to pointers in C++
(10 answers)
Closed 4 years ago.
I have two function signatures in C++
void printArray(int* arrayPtr);
void printArray(int*& arrayPtr);
I understand the 1st function. It says the function takes in a arrayPtr argument which is of type that's a pointer pointing to an integer.
Both function signature works, but I have a hard time understanding the 2nd signature(*&) and what benefits it offers?
It's exactly the same as type versus type&; the first is a value and the second is a reference. The fact that type is a pointer doesn't change that.
This question already has answers here:
determine size of array if passed to function
(10 answers)
Closed 4 years ago.
Suppose I have a function like this:
void MyFun(MyClass* p){
}
Where p is actually an unknown length array. How can I overloaded it to accept an array of rvalue MyClass.
Basically, you cannot - since being an rvalue is not really a proper part of the type system. There's no "pointer to rvalue T" or anything like that. Also, because using a pointer means that the pointed-to object could be any subclass of MyValue (that is also a reason I would not try something like reinterpreting the pointer as an std::array<MyClass, 123>, even if I knew the length to be 123).
I suggest you wrap your raw array in some class (dumb name for it: BunchOfMyClasses), and have:
void MyFun(const BunchOfMyClasses &);
void MyFun(BunchOfMyClasses &&);
as the overloads.