Array sizes in C++ must be constant at compile-time, so the answer is sort of.
If your function is constexpr
and called as part of a constant expression, then it can be used to statically set the size of the array. For example:
constexpr std::size_t square(std::size_t n) { return n * n; }
int my_array[compute_size(2)]; // array of 4 integers
However, this only works if you know all the data up-front at compile-time. If you are working with runtime values, such as things coming from files or from a user, then this will not work -- and you will have to resort to some other form of dynamic memory to handle this. In C++, generally this would be handled by a container such as a std::vector
:
std::size_t compute_size() { /* some computation based on runtime */ }
// ...
auto vec = std::vector<int>{};
vec.reserve(compute_size()); // reserve the size up-front
vec.push_back( ... ); // push_back or emplace_back any data you need
If you reserve
the size up front, you are able to avoid reallocation costs from push_back
/emplace_back
, provided you don't exceed the capacity.
Alternatively, you can initialize a vector of entries by doing either:
auto vec = std::vector<T>{};
vec.resize(N);
or
auto vec = std::vector<T>(N);
The difference here is that reserve
only changes the capacity, which means you can't actually index up to N
until you insert the elements -- whereas resize
or vector<T>(N)
will zero-initialize (fundamental types like ints) or default-construct (aggregate/class types) N
instances immediately, which allows indexing.
Generally, reserve
+ push_back
is better unless you know you want default-constructed / zero values.