I have initiated an array of 6 elements and tried to print it using a function called 'print'. I have used array object from the stl library. I passed the address of the array object to the print function. When I tried to change the value of the array object in the print function I am getting mismatched types error.
#include <bits/stdc .h>
using namespace std;
void print(array<int, 6> *arr){
for(int i : *arr){
cout<<i<<" ";
}
*(*arr 2)=2;
cout<<endl;
}
int main(){
array<int, 6> arr2={1, 2, 3, 4, 5, 6};
print(&arr2);
print(&arr2);
}
CodePudding user response:
In *(*arr 2)=2; you deference the array pointer and try to add 2 to it and then dereference that result to assign 2. I assume you want to assign 2 to the element at index 2 in the array.
You do not need to use pointers here though, take the array by reference.
And, never #include <bits/stdc .h>.
#include <array> // include the proper header files
#include <iostream>
void print(std::array<int, 6>& arr) { // by reference
for (int i : arr) {
std::cout << i << ' ';
}
arr[2] = 2; // assign 2 to the element at index 2
std::cout << '\n'; // std::endl flushes the stream which is usually uncessary
}
int main() {
std::array<int, 6> arr2 = {1, 2, 3, 4, 5, 6};
print(arr2); // and don't take the array address here
print(arr2);
}
If you really want to use a pointer here, this could be an option:
#include <array>
#include <iostream>
void print(std::array<int, 6>* arr_ptr) { // pointer
if (arr_ptr == nullptr) return; // check that it's pointing at something
std::array<int, 6>& arr = *arr_ptr; // dereference it
for (int i : arr) {
std::cout << i << ' ';
}
arr[2] = 2;
std::cout << '\n';
}
int main() {
std::array<int, 6> arr2 = {1, 2, 3, 4, 5, 6};
print(&arr2);
print(&arr2);
}
CodePudding user response:
This statement
*(*arr 2)=2;
does not make a sense. For example the operator is not defined for the class template std::array and as a result this expression *arr 2 is invalid.
You could write
( *arr )[2] = 2;
or for example
*( ( *arr ).begin() 2 ) = 2;
CodePudding user response:
*(*arr 2)=2;
Would be equivalent to
(*arr)[2] = 2;
if arr were a pointer to an array. I assume that's what you are looking for. But a std::array instance is not an array in that sense. It is an object encapsulating an array, and emulating some of the properties of the underlying array, but it cannot be used interchangeably with the underlying array. In particular, std::array objects do not decay to pointers as actual arrays do, and your code appears to be trying to rely on that.
You could instead do
*((*arr).data() 2) = 2;
or, more idiomatically,
*(arr->data() 2) = 2;
to leverage that array-to-pointer decay. Or you could do
arr->data()[2] = 2;
. But none of those is as clear or straightforward as the ...
(*arr)[2] = 2;
... already mentioned, which is what you should do if you must work with a pointer to a std::array instead of a reference to one.
CodePudding user response:
First note that std::array has no operator . So when you wrote the expression:
*arr 2 // INCORRECT
In the above expression, you are dereferencing the pointer to std::array and then adding 2 to the result. But as i said at the beginning, that there is no operator for std::array, this expression is incorrect.
Limitation
Second you program has a limitation which is that the function print can accept a pointer to an std::array with only 6 elements. So if you try to pass a pointer to an std::array of some different size then your program won't work.
Solution
You can fix these by:
- Passing the
std::arrayby reference. - Using templates. In particular, using template nontype parameter.
The advantage of using template nontype parameter is that now you can call the function print with an std::array of different size as shown below.
#include <iostream>
#include <array>
template<std::size_t N>
void print(std::array<int, N> &arr){ //by reference
for(const int &i : arr){
std::cout<<i<<" ";
}
arr.at(2) = 2; //use at() member function so that you don't get undefined behavior
std::cout<<std::endl;
}
int main(){
std::array<int, 6> arr2={1, 2, 3, 4, 5, 6};
print(arr2);
std::array<int, 10> arr3 = {1,2,4,3,5,6,7,8,9,10};
print(arr3);
}
Some of the modifications that i made include:
- Removed
#include <bits/stdc .h>and only included headers that are needed. - Used templates. In particular, removed the limitation by using template nontype parameter.
- Passed the
std::arrayby reference. That is, there is no need to pass a pointer to anstd::array. We can just pass thestd::arrayby reference. - Used
at()member function so that we don't go out of bounds and so that we don't get undefined behavior.
