0

I want to create a function that resizes a stack. It will create a new array with a larger or smaller size depending on the value of max, then copy the elements into that new array.

void resize(const int& max) {
    std::array<Item, max> temp;
    for (int i = 0; i < n; i++) {
        temp.at(i) = a.at(i);
    }
    a = temp;
}

I know this will not run because max is not a constant expression. I absolutely don't know how to pass a constant int value. I tried:

void resize(constexpr int& max) //compiler says cannot make int arg constexpr

I don't want to do constexpr void resize because I don't need the function to be evaluated at compile time, and it didn't work anyway.

Note: I know this might be easier if I used std::vector because it's resizable, but I want to try to experiment with std::array.

What should I do?

lightning_missile
  • 2,821
  • 5
  • 30
  • 58
  • 1
    I'm not sure about the stack resizing stuff but from what you describe you want [`std::dynarray`](http://en.cppreference.com/w/cpp/container/dynarray) instead of `std::array`. – Drax Nov 06 '14 at 09:16
  • What you should do is not use an `std::array`, as they are not dynamically sizeable and not the right tool for this job. Either use an `std::vector` or an `std::dynarray`, with `vector` being more appropriate given your need for dynamic resizing. Related: http://stackoverflow.com/questions/19111028/stddynarray-vs-stdvector and http://stackoverflow.com/questions/756906/can-you-resize-a-c-array-after-initialization – Jason C Nov 06 '14 at 09:18
  • Even with your pseudo-code, `a = temp` won't compile given `stack::operator=` is only defined when assigning from another stack, and further even if you derive to access the `protected` container and `assign` it may not change the capacity of your stack `a`. You're better off exposing the `deque` (assuming you stick to the default container) and using [`shrink_to_fit`](http://en.cppreference.com/w/cpp/container/deque/shrink_to_fit) or the old swap-with-a-just-big-enough-stack/deque trick. – Tony Delroy Nov 06 '14 at 09:32
  • Is int the beter choice here for the container size ? Or should he use size_t instead ? – MokaT Nov 06 '14 at 13:40
  • 1
    @MoKat size_t would be more semantically accurate and appropriate and you can find much about it vs. int online. – Jason C Nov 06 '14 at 17:50

1 Answers1

4

I think you are mistaking compile-time constant and run-time constant. You cannot use std::array in this way. You want a container whose size is not compile-time constant, and that would be std::vector.

If you want your container's size to be constant throughout the runtime, you can either rely on self discipline (i.e : do not use push_back() or resize() etc..) Or you could write a wrapper class (.i.e a class that has-a std::vector as a member) and choose the methods of this class carefully to never resize the vector.

You can also use dynarray but it has been rejected from c++11 (and c++14 If I recall correctly)

PS: it is quite weird to name your method resize() and then say that you want constant-sized arrays =) You do realize that if you call this method you are indeed changing the size of your array at runtime, in which case why not use std::vector and be done with it ?

Félix Cantournet
  • 1,941
  • 13
  • 17
  • There is also `std::dynarray`, which is not quite the best tool for the job but is more inline with the OP's experimentation. – Jason C Nov 06 '14 at 09:20
  • "I think you are mistaking compile-time constant and run-time constant." This also applis to you if you advice that "Another way to do this would be to use a templated resize function." Since the template paramter is compile time anyaway :D – Drax Nov 06 '14 at 09:20
  • @Félix can you give an example on how to do this in templated resize function? Thanks – lightning_missile Nov 06 '14 at 09:22
  • @recursivePointer This is a bad idea. Don't do it. – Félix Cantournet Nov 06 '14 at 11:21
  • 1
    @JasonC `std::dynarray` is not part of C++ standard though – Anton Savin Nov 06 '14 at 13:00
  • @recursivePointer The point is not that std::vector is resizable, the point is that std::vector isn't compile-time constant in size. std::array is compile-time constant in size. it means that ready your code, without executing it, I can know what size it will be, because it is a template parameter. You should read about templates to understand better how they work. – Félix Cantournet Nov 06 '14 at 13:20
  • @Anton Its not the best choice in general. – Jason C Nov 06 '14 at 17:46