0

It seems parameter passed in functions cannot maintain their const property. Say that I need to initialize a const variable using information from parameters within a function, then create an array type. How can I do?

example:

#include <array>
using namespace std;

void foo(const int info)
{
    const int num = info + 1;  // seems num cannot be constant
    array<int, num> arr;
}

compile error:

test.cpp: In function ‘void foo(int)’:
test.cpp:8:16: error: the value of ‘num’ is not usable in a constant expression
 array<int, num> arr;
            ^
test.cpp:7:15: note: ‘num’ was not initialized with a constant expression
     const int num = info + 1;  // seems num cannot be constant
               ^

Update: using array type would cause trouble like that, but using simple type array is just ok:

void foo(int info)
{
    int array[info];
}

Isn't info should be assigned during compile time?

JiangFeng
  • 355
  • 2
  • 14
  • 1
    What is the actual compiler error you're getting? Note that you cannot use a runtime variable as a template parameter argument (`const` is not the same thing as `constexpr`). – Dai Aug 27 '17 at 04:07
  • 1
    Num needs to be a compile-time constant doesn't it if you want to use it as the size for an array? `const` means it can't be reassigned, not that it's a constant at compile time afaik – Carcigenicate Aug 27 '17 at 04:07
  • 1
    std::array requires a compile-time constant. A function parameter cannot be a compile-time constant. You need std::vector instead. – Cody Gray - on strike Aug 27 '17 at 04:07

3 Answers3

1

In C++ there is a difference between const and constexpr: Difference between `constexpr` and `const`

In your case, you are trying to create a compile-time sized array, which requires a constexpr. The constexpr cannot simply be a const variable function argument. You could use constexpr instead, or you could use vector (runtime sized array) instead of array.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • Thanks a lot, I read about constexpr, but still, I cannot understand how to make a function parameter used as constexpr. Can you give me an example? – JiangFeng Aug 27 '17 at 07:21
  • @JiangFeng: If you want to make a function parameter be a constexpr, you can make it a template parameter, as shown by Jeff Garrett's answer here. You cannot make it a regular argument as you have done. Most of the time, you should just use `vector` instead of `array` for this sort of code. – John Zwinck Aug 27 '17 at 13:16
1

If you compile with gcc -pedantic, you will see that int array[info] is also not standard C++. See the GCC docs.

One way to accomplish the goal of the question is a non-type template parameter:

#include <array>

template<int info>
void foo()
{
    constexpr int num = info + 1;
    std::array<int, num> arr; // or int arr[num]
}
// Call as foo<3>()
Jeff Garrett
  • 5,863
  • 1
  • 13
  • 12
0

If you need a dynamically sized array and you don't need the specific properties of std::array, you can just use vector.

Main difference is:

std::array is a template class that encapsulate a statically-sized array, stored inside the object itself, which means that, if you instantiate the class on the stack, the array itself will be on the stack. Its size has to be known at compile time (it's passed as a template parameter), and it cannot grow or shrink.

Vectors internals, however, are stored on the heap.

From: https://stackoverflow.com/a/4424658/128581

Further std::array is trivially copyable (meaning you can memcpy it from one place to another without worrying) if the type T is trivially copyable.

Use vector like:

void foo(size_t size)
{
  vector<int> arr(size);
}
Josh
  • 12,602
  • 2
  • 41
  • 47