Reputation: 316
I dynamically created an array using a function like this:
//..
double ** allocate_2d(const int wd1, const int wd2){
double **array = new double*[wd1];
for(int idx=0; idx<wd1; idx++)
{
array[idx] = new double[wd2];
}
return array;
}
I would like to pass the resulting array into a function as a constant parameter. I want the array to be "read only" within the function.
func(const double ** array)
{
// computations using array
}
However I get the following error:
invalid conversion from ‘double**’ to ‘const double**’
Is it possible to do something like this?
Upvotes: 4
Views: 881
Reputation: 12779
The reason why OP's signature
func(const double ** array){
// computations using array
}
generates an error when a double **
is passed as an argument, lies in the rules of qualification conversions.
Quoting https://en.cppreference.com/w/cpp/language/implicit_conversion (emphasis mine):
Qualification conversions
- A prvalue of type pointer to cv-qualified type T can be converted to a prvalue pointer to a more cv-qualified same type T (in other words, constness and volatility can be added).
- [...]
"More" cv-qualified means that
- a pointer to unqualified type can be converted to a pointer to const;
- [...]
For multi-level pointers, the following restrictions apply: a multilevel pointer P1 which is cv10-qualified pointer to cv11-qualified pointer to ... cv1n-1-qualified pointer to cv1n-qualified T is convertible to a multilevel pointer P2 which is cv20-qualified pointer to cv21-qualified pointer to ... cv2n-1-qualified pointer to cv2n-qualified T only if
- the number of levels n is the same for both pointers;
- if there is a const in the cv1k qualification at some level (other than level zero) of P1, there is a const in the same level cv2k of P2;
- [...]
- if at some level k the P2 is more cv-qualified than P1, then there must be a const at every single level (other than level zero) of P2 up until k: cv21, cv22 ... cv2k.
- [...]
- level zero is addressed by the rules for non-multilevel qualification conversions.
char** p = 0; const char** p1 = p; // error: level 2 more cv-qualified but level 1 is not const const char* const * p2 = p; // OK: level 2 more cv-qualified and // const added at level 1Note that in the C programming language, const/volatile can be added to the first level only:
char** p = 0; char * const* p1 = p; // OK in C and C++ const char* const * p2 = p; // error in C, OK in C++
So, to enforce constness, the signature needs to be changed into
void func(double const * const * array) {
// ... ^^^^^
}
That said, I strongly suggest to change the overall design and avoid that dynamically allocated jagged array, if possible.
Upvotes: 4
Reputation: 2121
You can use const_cast
to add constness to an object (explicit cast is needed).
double **p = allocate_2d(100,200);
// populate p
func(const_cast<const double**>(p));//array pointed by p will be read only inside func
Still, you need to consider whether you need const
there at all.
Upvotes: -2