0

I want to convert a float vector to a float array in C++ 20. I searched online and found this solution:

#include <iostream>
#include <algorithm>
#include <vector>
 
int main()
{
    std::vector<int> input({ 1, 2, 3, 4, 5 });
 
    int arr[input.size()];
    std::copy(input.begin(), input.end(), arr);
 
    for (int i: arr) {
        std::cout << i << ' ';
    }
 
    return 0;
}

But when I try to implement it, the compiler gives me an error saying that what's inside the brackets in the array declaration must be a constant expression.

Since when is this the case? I swear I've declared arrays in a similar manner in C++ before and it worked. And if you look online you'll see that everyone does this too, the example I posted seems to be the standard solution to my problem. So why does it give me an error?

Jarod42
  • 203,559
  • 14
  • 181
  • 302
Pepis
  • 9
  • 1

1 Answers1

9

Since when is this the case?

Since always. In standard C++, you cannot allocate a block of memory on the stack if you don't know its size at compile time.

Some compilers allow it as an extension. It's also standard in C99, and these arrays are then known as variable-length array.

A lot of what you see online is non standard. Just because someone does something that works for them doesn't mean it will work for you. In this case, it can certainly work for you if you don't care about writing cross-platform, standard compliant code. But if you want to write standard compliant code, you have basically two choices: make an array with a large enough size, known at compile time, and only use part of it, or don't use an array.

To address your comment:

Because a third party function (OpenGL) requires an array as an argument.

No function requires an array as argument. It can require a raw block of memory, but then you also need to give it the size of that block. You can easily do that with a std::vector, using the methods data() and size().

The only way I know of to require an array as argument is through some template magic:

template<std::size_t N>
void print_size(int (&array)[N]) {
    std::cout << N;
}

Demo

Even then, you can apparently pass it a vector if you specify the size (might be undefined behavior):

std::vector<int> v = {1, 2, 3};
print_size<3>(reinterpret_cast<int(&)[3]>(*v.data()));
Nelfeal
  • 12,593
  • 1
  • 20
  • 39