I work with multiple arrays at a time. There are functions which need to change the arrays, others only need to read. Take for instance these functions:
// Only needs to read from the two arrays.
void f(int const *a[2]) { /* ... */ }
// Changes the two arrays.
void g(int *a[2]) { /* ... */ }
I would expect that I could call them both with a non-const array. Adding a
right-most const is always possible, a const on the left does change the
type. Still I would think that a const there would only make it stricter and
should be possible.
A data structure might look like this:
int *a[2] = {new int[10], new int[10]};
Calling g is not a problem, that compiles cleanly:
g(a);
However, when I try the same with f, it does not work:
f(a);
g++:
const_cast.cpp: In function 'int main(int, char**)':
const_cast.cpp:12:8: error: invalid conversion from 'int**' to 'const int**' [-fpermissive]
f(a);
^
The message that clang++ gives is slightly different:
const_cast.cpp:12:5: error: no matching function for call to 'f'
f(a);
^
const_cast.cpp:4:6: note: candidate function not viable: no known conversion from 'int *[2]' to 'const int **' for 1st
argument
void f(int const *a[2]) {}
^
Then I have tried to use a const_cast to force this conversion:
f(const_cast<int const(*)[2]>(a));
That does not work, because it changes the number of indirections as well.
const_cast.cpp:22:36: error: invalid const_cast from type 'int**' to type 'const int (*)[2]'
f(const_cast<int const(*)[2]>(a));
^
I do not want to relax the requirement on f, though. It should be clear to
the user that this function will not alter the contents of the array. Also
there are other cases in the codebase that I do not want to change.
Creating a new variable with the right const does work, however:
int const *const_a[2] = {a[0], a[1]};
f(const_a);
Is there a simpler way to do this?
std::arrayif the size is known at compile time, orstd::vectorif the size is dynamic. In addition to all other advantages you gain, you also get a simpler declaration syntax where addingconstat the right place is trivial.