-1

Arrays require a constant to initialize the size. Hence, int iarr[10]

I thought I could possibly take a non-const argument and convert it to const then use it for an array size

int run(int const& size);
int run(int const& size)
{
    const int csize = size;

    constexpr int cesize = csize;

    std::array<int, cesize> arr;
}

This, unfortunately doesn't work and I thought of using const_cast as

int run(int& size);
int run(int& size)
{
    const int val = const_cast<int&>(size);

    constexpr int cesize = val;

    std::array<int, cesize> arr;
}

and this won't work either. I've read through a few SO posts to see if I can find anything

cannot-convert-argument-from-int-to-const-int
c-function-pass-non-const-argument-to-const-reference-parameter
what-does-a-const-cast-do-differently

Is there a way to ensure the argument is const when used as an initializer for the size of an array?

EDIT: I'm not asking why I can't initialize an array with a non-const. I'm asking how to initialize an array from a non-const function argument. Hence, initialize-array-size-from-another-array-value is not the question I am asking. I already know I can't do this but there may be a way and answer has been provided below.

Mushy
  • 2,535
  • 10
  • 33
  • 54
  • 1
    Possible duplicate of [initialize array size from another array value](https://stackoverflow.com/questions/4589463/initialize-array-size-from-another-array-value) – JimmyB Oct 16 '17 at 15:32
  • @JimmyB the OP of that question _really_ needs to switch the accepted answer, though it's not directly applicable to OP's example – underscore_d Oct 16 '17 at 15:33
  • Looks like you're trying to create a variable-length array (which is an advanced C feature with various drawbacks and not actually supported in C++). Since the size comes from a parameter (and your function is not `constexpr`), its value will only be known at run-time. Creating a fixed-size array requires the size to be known at compile-time in order to instantiate the right template (or in general, allocate the right amount of memory). – Cameron Oct 16 '17 at 15:53
  • Thought experiment: If it were allowed what you just showed, why not just drop the whole requirement that the size has to be a constant, since the work around is just assigning the value to a constant? – Rakete1111 Oct 17 '17 at 18:55
  • @Rakete1111 If I was allowed to pass a non-const argument to initialize an array or `std::array` this question itself wouldn't even exist. – Mushy Oct 17 '17 at 20:54

2 Answers2

3

std::array is a non-resizable container whose size is known at compile-time.

If you know your size values at compile-time, you can pass the value as a non-type template argument:

template <int Size>
int run()
{
    std::array<int, Size> arr;
}

It can be used as follows:

run<5>();

Note that Size needs to be a constant expression.


If you do not know your sizes at compile-time, use std::vector instead of std::array:

int run(int size)
{
    std::vector<int> arr;
    arr.resize(size); // or `reserve`, depending on your needs
}

std::vector is a contiguous container that can be resized at run-time.

Vittorio Romeo
  • 90,666
  • 33
  • 258
  • 416
  • 6
    @Mushy: this is basic C++ knowledge. Have you read an introductory C++ book? Additionally, the cppreference pages for `std::array` and `std::vector` should help you. – Vittorio Romeo Oct 16 '17 at 15:38
  • This may be basic C++ knowledge but to you but, had I read this in a book, I wouldn't be asking this question on Stack. Also, I don't want to use a `std::vector` and a `std::array` requires a const size. Nevermind. – Mushy Oct 16 '17 at 15:41
  • @Mushy: why don't you want to use `std::vector`? Do you know your sizes at compile-time? – Vittorio Romeo Oct 16 '17 at 15:43
  • 2
    @Mushy: added more information and links. They should contain all the information you need. BTW, I find it hard to believe that your book explained `constexpr` and `const_cast` before `std::vector` and templates. What book did you read? – Vittorio Romeo Oct 16 '17 at 15:46
  • Because I wanted to use either an `array` or `std::array` using your answer to answer my question. I understand I should avoid array usage and opt for container behavior instead. – Mushy Oct 16 '17 at 15:49
  • 1
    I'm reading `The C++ Programming Language (C++11) Stroustrup` and `C++ Primer (C++11) Lippman` and, where I am in both books, Stroustrup covered `function templates`, constexpr`, and `const`. Lippman covered `constexpr` and `const` but neither book has indicated I can do this for arrays and both books have covered arrays so far. Thus, my need to ask a worldwide audience because neither book can teach everything there is to know. – Mushy Oct 16 '17 at 16:02
  • 1
    @Mushy: fair enough - my answer + links should help you. Let me know if you have any particular further question. – Vittorio Romeo Oct 16 '17 at 16:07
0

I'm asking how to initialize an array from a non-const function argument.

As you saw, it is not possible initialize an array size with an variable, because you need to specify the size or array at compiler time.

To solve your problem you should use std::vector that works like an array but you can resize it at run time. You can handle de vector as if you were handled an array, using the operator [], for example:

class MyClass
{
  vector<char> myVector; 
public:
  MyClass();

  void resizeMyArray(int newSize);
  char getCharAt(int index);
};

MyClass::MyClass():
  myVector(0) //initialize the vector to elements
{

}

void MyClass::resizeMyArray(int newSize)
{
  myVector.clear();
  myVector.resize(newSize, 0x00);

}

char MyClass::getCharAt(int index)
{
  return myVector[index];
}

For more information check this link: http://www.cplusplus.com/reference/vector/vector/

Upgrade: Also, considere that std::array can't be resize, as this links say:

Arrays are fixed-size sequence containers: they hold a specific number of elements ordered in a strict linear sequence.

Jorge Omar Medra
  • 978
  • 1
  • 9
  • 19