I have looked at all the other posts with a similar topic, and none help, so please don't flag as a duplicate.
I am defining in main()
a const int SIZE = 20;
. Then, I pass this as an argument to my function, Mode:
int* Mode(int* numbers, int & mode, const int SIZE)
{
int occurences[SIZE];
// Calcualte mode
}
However, I get the error, expression must have a constant value
.
My function call (in main) looks like this:
int* occurencesPtr = Mode(numbersPtr, mode, SIZE);
With SIZE
being defined at the beginning to the literal 20
.
I understand that the error is because the function's version of SIZE
only acquires its value when the function is called (?), but I don't know how I could work around this.
I have even tried passing to the function a const int * const SIZEPtr = &SIZE
, but that didn't work either. Help?
EDIT: I am not trying to use a variable size!! Notice that I have made SIZE
a const
everywhere! I just want to use that same SIZE constant to declare my array.
EDIT: Dynamic arrays are not what I need. I just want a normal, named, array, defined with a constant size value passed to the function.
Answer
There is a misconception here with what const
means, probably because it's a little confusing that this works:
const int SIZE = 20;
int array[SIZE];
but this doesn't:
void foo(const int SIZE) {
int array[SIZE];
// ...
}
const int SIZE = 20;
foo(SIZE);
The issue is that the array size in an array declaration must be a core constant expression. Simplified, that means an expression that's evaluatable at compile time to be a constant. That is true in the first case (you can see that SIZE
is the integral constant 20
) but that is not true in the second case. There, the SIZE
function parameter is just const
- in the sense that it is nonmodifiable - and not a core constant expression. You can see the difference in that I can call foo()
with something that is clearly unknowable until runtime:
int x;
if (std::cin >> x) {
foo(x);
}
In order to pass an argument into foo
, and have that argument be used as an array bound, it is not enough to have it be const
- the actual integral value must be encoded into the type (unless you call foo()
as constexpr
which I'm assuming is not the case here). In which case, you'd have to do something like:
template
void foo() { ... }
const int SIZE = 20;
foo();
or:
template
void foo(std::integral_constant ) { ... }
const int SIZE = 20;
foo(std::integral_constant{} );
or simply have SIZE
be a global constant or otherwise accessible to foo()
in a way that doesn't have to do with its arguments.
Or, there's always the simple option: use std::vector
:
void foo(const int SIZE) {
std::vector v(SIZE);
...
}
No comments:
Post a Comment