1

I have a simple program:

#include <array>
#include <iostream>
#include <functional>
#include <algorithm>

using namespace std;

int main(){
    array<int, 5> myArr = {3, 10, 0, 5, 7};
    int badNum = 0;
    for(int item : myArr){
        cout << item << endl;
    }

    cout << "\n" << endl;
    cout << "\n" << endl;

    sort(myArr.begin(), myArr.end(), greater<int>());

    for(int item : myArr){
        cout << item << endl;
    }

    array<int, 4> goodFour;

    for (unsigned int i = 0; i < myArr.size(); i++){
        if(myArr[i] != badNum){
            // goodThree.append(myArr[i]); <-- This is where I am stuck
        }
    }

}

I am stuck on trying to assign an element to a std::array. I know in std::vector I can use push_back method, but on a std:array, how to assign to the next (not yet assigned) element? I am coming from Python 3.x where we have the append method for a list. I am not attempting to change the size of the array, instead, I am trying to fill in the allocated spaces with values.

I have looked at:

http://www.cplusplus.com/forum/beginner/67707/

http://www.cplusplus.com/forum/beginner/86394/

http://www.cplusplus.com/forum/beginner/152125/

But these are all for vectors or the primitive int[5] myArr types, not std::array.

JaMiT
  • 14,422
  • 4
  • 15
  • 31
artemis
  • 6,857
  • 11
  • 46
  • 99
  • Possible duplicate of [How to add element to C++ array?](https://stackoverflow.com/questions/755835/how-to-add-element-to-c-array) – GAVD Sep 27 '19 at 01:40
  • That isn't a duplicate at all, in fact, it specifically mentions using `std:array`, not the older `int[x] myArr` version, and specifically mentions not using a vector. @GAVD – artemis Sep 27 '19 at 01:54
  • @JerryM. I've reworded your question based upon the comments to my answer. Feel free to revert if I missed the point. – JaMiT Sep 27 '19 at 02:13

3 Answers3

1

If you only want the first three good numbers you would maintain a pointer to the next index to insert at:

for (int i = 0, k = 0; k < 3 && i < myArr.size(); i++) {
  if (myArr[i] != badNum) {
    goodThree[k++] = myArr[i];
  }
}

If you want all the numbers that are good you would use a std::vector and call its push_back method:

std::vector<int> goodThree;
for (int i = 0; i < myArr.size(); i++) {
  if (myArr[i] != badNum) {
    goodThree.push_back(myArr[i]);
  }
}
David G
  • 94,763
  • 41
  • 167
  • 253
  • Is there no way to achieve this _without_ using a vector? There is nothing in the `std::array` that has a `push_back` method? – artemis Sep 27 '19 at 01:54
  • 1
    @JerryM. You set the size of the array when you created it. Just like a normal array `int[N]`, there is no way to extend it, it is set in stone when you make it. Adding an arbitrary number of elements is what `std::vector` is for. – David G Sep 27 '19 at 01:55
  • But what if I _know_ how many elements will be added to it? That is the pointer method you describe above? – artemis Sep 27 '19 at 01:58
  • 1
    @JerryM. Yes, and if you know the number of elements then you have to specify that number when you create the array. In your case you replace `N` in `array` with that number. If you know there will be 3 elements, then `array` is fine. If you don't know the number of elements use a vector. – David G Sep 27 '19 at 02:00
  • The question was more so if I _**know**_ the size, how do I add an element to a fixed size `std::array`. I didn't know I needed to use pointers. As the post said, I was looking for a `append` method or `push_back` method available to `std::array`. I didn't know I needed pointers. – artemis Sep 27 '19 at 02:03
  • @JerryM. When I use the term "pointer", I didn't mean an actual `T*` pointer. I meant you would hold a variable whose value was the index of the next place to insert the value. You don't *have* to use real pointers (though you can). Also, there is no `append` or `push_back` method. `std::array` is modeled after a raw C array, so the way you would insert is the same way you would do it for a C array (which is the way I did it). – David G Sep 27 '19 at 02:06
  • @JerryM. I want to make sure that you understand. Is there anything you still don't get from my explanation? – David G Sep 27 '19 at 02:10
  • I get that now. I was looking for a way to arbitrarily add elements to the array structure, but I think I needed a better understanding of what that structure is, which I have now, so thank you – artemis Sep 27 '19 at 02:12
0

The size of std::array is fixed at compile time. If you need to append another value at run time, then you have to use std::vector (or something like it). The closest you can get to "appending" to a std::array is if you copy its contents into an array with one more element that contains the "appended" value. You can use some template metaprogramming techniques to make this easier:

template <typename T, std::size_t N, typename X, std::size_t... I>
std::array<T, N + 1> push_back(std::array<T, N> const& a, X&& x, std::index_sequence<I...>) {
  return {std::get<I>(a)..., std::forward<X>(x)};
}

template <typename T, std::size_t N, typename X>
std::array<T, N + 1> push_back(std::array<T, N> const& a, X&& x) {
  return detail::push_back(a, std::forward<X>(x), std::make_index_sequence<N>());
}

Example of use:

std::array<int, 2> a = {1, 2};
std::array<int, 3> b = push_back(a, 3);

for (int x : b) {
  std::cout << x << "\n";
}
Joseph Thomson
  • 9,888
  • 1
  • 34
  • 38
  • Nothing in my post indicates changing the size of the array. If I declare an array of size 3, but it is blank, how do I add an element into it in a loop format as described above? – artemis Sep 27 '19 at 02:02
  • 1
    @JerryM. Keep track of how many values it "contains" (according to your program logic) in a separate variable? – Joseph Thomson Sep 27 '19 at 02:06
0

The size of a std::array is set at compile time. This means that you cannot "append" values to a std::array at run time. However, you could track how many values your array "contains" by your own program logic. For example:

std::array<int, 5> a = {1, 2, 3, 4, 5};
std::array<int, 4> b;

std::size_t n = 0;

for (int x : a) {
  if (x != 2) {
    if (n < std::size(a) - 1) {
      b[n++] = x;
    } else {
      throw std::out_of_range("array is full");
    }
  }
}
Joseph Thomson
  • 9,888
  • 1
  • 34
  • 38