1

I'm writing a programm to create a roster. Every month has a different number of shifts, which is determined by a function. At the beginning of the programm the user enters the month, the according number of shifts gets calculated in a function and then I want to create a 2-dimensional array with that size. But aparrently I can't initialize an array like this. Can anyone help me out?

As you may have noticed, I'm a very inexperienced beginner, so I apologise for not expressing myself perfectly in advance.

//function to calculate number of shifts
const int getShift(const int month, const int year) {
    ...
    return x;
}

int main(){
int array[getShift(8,2019)[2];
}

I got an error along the lines of "expression did not evaluate to a constant" although that number actually is a constant, or at least I want it to be one...

Thanks in advance for your help!

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Nico
  • 21
  • 3

2 Answers2

3

The function must to be declared with the specifier constexpr and accordingly to satisfy the requirements for constexpr functions..

Here is a demonstrative program

#include <iostream>

constexpr int getShift( int x, int y )
{
    return y / x;
}

int main()
{
    int array[getShift(8,2019)][2];

    std::cout << sizeof( array ) / sizeof( *array ) << '\n';
}

Its output is

252

Here is a list of requirements for the body of constexpr functions (C++20)

(3.4) — its function-body shall not enclose (Clause 8)

(3.4.1) — an asm-definition,

(3.4.2) — a goto statement,

(3.4.3) — an identifier label (8.1),

(3.4.4) — a definition of a variable of non-literal type or of static or thread storage duration or for which no initialization is performed.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • downvote might come from old c++ users whose experience limited to c-like c++, I guess. – Feng Wang Aug 11 '19 at 13:19
  • @VladfromMoscow `sizeof( array ) / sizeof( *array )` - We have [std::size](https://en.cppreference.com/w/cpp/iterator/size) for that these days. – Jesper Juhl Aug 11 '19 at 13:25
  • 1
    @JesperJuhl Yes we have but not all users use modern compilers.:) – Vlad from Moscow Aug 11 '19 at 13:26
  • The OP says *At the beginning of the programm the user enters the monthAt the beginning of the programm the user enters the month*, it's clear that `getShift depends` on user input so a `constexpr` is impossible. – john Aug 11 '19 at 13:28
  • @VladfromMoscow True, but (IMHO) the answer should use/advocate the modern way and then, maybe, mention the old way in a footnote. Or at least *mention* the modern way. – Jesper Juhl Aug 11 '19 at 13:28
  • 1
    @john But in his example he is using constants.:) – Vlad from Moscow Aug 11 '19 at 13:29
3

When you need an array with a dynamic size, almost always the best solution in C++ is to use a vector.

#include <array>
#include <vector>

//function to calculate number of shifts
int getShift(int month, int year) {
    ...
    return x;
}

int main() {
    std::vector<std::array<int, 2>> array(getShift(8,2019));
}

Since you need a 2D array, and since regular arrays can't be members of a vector, I've also used a std::array<int, 2> for the second dimension.

Now you can use array pretty much like a regular 2D array, in particular you can use array[i][j] to access individual elements of the 2D array.

john
  • 85,011
  • 4
  • 57
  • 81