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.
Related
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.
Everything in c++ , including the STL containers are passed by value . But the exception is Array which are passed by pointers . Right?
Why are arrays in c++ [eg: int a[5] ] are passed by pointers but the vectors are passed by value ? [By default]
edit: okay , std::array can be passed by value also , I wasn't aware of this .
code :
void fun_array(int a[])
{
a[0]=10;
}
void fun_vector(vector<int> v)
{
v[0]=10;
}
int main()
{
int a[5]={1,2,3,4,5};
vector<int> v={1,2,3,4,5};
fun_array(a);
fun_vector(v);
cout<<a[0]<<" "<<v[0];
}
output : 10 1
Everything is passed by value if you don't specify otherwise. The case about C arrays is not an exception, but just that they degenerate into pointers. If you need a fixed size array in C++ code prefer using std::array instead of C arrays.
Then decide if you want to pass by value or by reference.
Related note: Even when passing containers, you might still want to pass by value, instead of by reference, if you are going to copy the container.
By default all function arguments in C++ are passed by value.
Your confusion comes from the fact that the name of an array is actually a pointer to the first element of the array (eg. for the array int a[6], a is a pointer to a[0].
Unless the function parameter is explicitly a reference to a pointer, even pointer arguments are passed by value.
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]) {}
This question already has answers here:
When a function has a specific-size array parameter, why is it replaced with a pointer?
(3 answers)
Closed 9 years ago.
I'm just curious what is the reason for the following error: I'm trying to determine the size of an integer array.
When I find the size of array in main function, this code returns correctly:
int program[12] = { 1007, 1008, 2007, 3008, 2109, 1109, 4300, 0, 0, 0, -99999 };
cout<<sizeof(program)/sizeof(program[0])<<"\n";
But if I pass program to a function by value, it always return 2:
void Sipmletron::load(int program[])
{
int length=sizeof(program)/sizeof(program[0])
std::cout<<length<<"\n";
memory= new int[length];
}
You cannot pass arrays by value. The argument is passed as a pointer to the first element of the array, so you are in effect calculating sizeof(int*) / sizeof(int).
When an array is passed in C++ (and in C), it looses it's size (it's passed as the address of the first element, no matter whether it is int * or int []).
You can use std::array if you are using C++11, which has a size() member function, similar to vector. In almost all other aspects, it is the same as a standard C style array.
Otherwise, you have to pass the size along with the array - or use some marker to indicate the end (looks like you already have that with -99999).
There are two special-case language rules at play here, both inherited directly from C.
An expression of array type, in most contexts, is implicitly converted to ("decays to") a pointer to the array's first element. The exceptions in C are when the expression is the operand of unary & or sizeof, or when it's a string literal in an initializer used to initialize an array (sub)object. C++ has more exceptions, but none that apply here.
A parameter defined as some_type foo[] is "adjusted" to some_type *foo, so your parameter program is really a pointer, not an array. (This adjustment occurs only for parameter declarations.)
These rules (unfortunately IMHO) work together to make it appear that you're passing an array object by value, and accessing an array inside your function, but in fact it's all pointers.
You could do this with templated member functions if you really wanted to:
template <size_t N>
void Sipmletron::load(int (&program)[N])
{
size_t length = N;
std::cout << length << "\n";
memory = new int[length];
}
In addition, and even without seeing the rest of your code, I'm feel sure it would be worth your while looking at using a std::vector instead of doing your own memory management using new, with a more idiomatic load(...) that used iterators.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C++ return array from function
I am trying to declare a function that returns an array of void pointers. I have the following code:
void *[] get_functions();
However I get the compilation error: expected unqualified-id before '[' token
Is what I'm trying to do valid, and if so what is my syntax error?
EDIT
In reply to some of the comments, I am trying to return an array (which now will probably be a vector) of functions, which I can then randomly select one and call it. What would you suggest instead of void *?
EDIT 2
The type of functions returned will have a fixed signature (not decided yet), Let's for arguments sake say the signature will be int f(int i, int j) what would the return of my get_functions function look like, or will vector<void*> still be appropriate?
C++ doesn't allow a function to return an array. You should probably return a vector instead:
std::vector<void *> get_functions();
There are two issues with your approach. The first of which is that you cannot return arrays from functions. In C you would return a pointer to the elements in the array, but that implies that you need to manage the memory. In C++ you can use a container, like std::vector instead of the array, and that can be returned by value.
The second issue is that you are returning function pointers, and the conversion from function pointer to void* is not guaranteed by the standard. The alternatives here start with returning a function pointer of the appropriate type (i.e. std::vector<int (*)(int,int)>) or using higher level constructs like std::function (C++11, or boost::function in C++03): std::vector<std::function<int(int,int)>>. The first approach is better suited for the description you provided as the types of the functions seem to be fixed and there will be little overhead in using the function pointers. The second approach is more generic as it can encapsulate anything that is callable with two int and return an int, including function pointers and function objects. That in turn allows you to adapt the signatures of other functions by means of std::bind or create lambdas with the appropriate signature: [](int x, int y){ return x*y;}
void **get_functions();
Later on you can then say:
void **pp = get_functions();
pp[5]; // This is the sixth pointer-to-void
If you don't already know the length of the array, you will need to pass it some other way -- for that reason, Jerry Coffin's answer is probably better.
you can just return void pointer to first element of the array. and you can cast it inside the calling function.
the array itself is passed/returned as a pointer.