1

I have a vector of elements of type uint8 which I am copying into one std::array. After some operations again I need to copy the elements from std::array to a vector.Please find the code below

/******************************************************************************

Welcome to GDB Online.
GDB online is an online compiler and debugger tool for C, C++, Python, Java, PHP, Ruby, Perl,
C#, VB, Swift, Pascal, Fortran, Haskell, Objective-C, Assembly, HTML, CSS, JS, SQLite, Prolog.
Code, Compile, Run and Debug online from anywhere in world.

*******************************************************************************/
#include <iostream>
#include <vector>
#include <array>
#include <cstdint>
#include <limits>
#include <algorithm>
std::array<std::uint32_t, 5> elem_arr ;
void copy_from_vector(std::vector<std::uint32_t> elem_vec)
{
    std::copy(elem_vec.begin(),elem_vec.end(),elem_arr.begin());
}
std::vector<std::uint32_t> copy_from_array()
{
    std::vector<std::uint32_t> ele_vec_copy {elem_arr.begin(),elem_arr.end()};
    return ele_vec_copy;
}
int main()
{

    std::vector<std::uint32_t> ele_vec {1,2,3};

    copy_from_vector(ele_vec);

    auto ele_vec_copy = copy_from_array();

    for(auto ele : ele_vec_copy)
        std::cout << ele << std::endl;

    return 0;
}
output:
======
1
2
3
0
0

Now the problem is my array size is 5 but vector having only 3 elements. when I copy the elements from the array to a new vector I am getting extra 2 zeros. How can I get the output as below

output:
======
1
2
3
goodman
  • 424
  • 8
  • 24
  • 1
    A `std::array` only knows it has five elements. It has no way of knowing that only three elements have been copied to it. If that's what you need to do, keep track in another variable of how many elements are actually copied, and use that variable to control your loops. Alternatively, designate a value as meaning "unused" and compare with that value to control your loops. Incidentally, your code for copying to the `std::array` will need to correctly handle being passed vectors with too many elements - that does not happen automatically. – Peter Feb 28 '20 at 06:49
  • The easiest way I see is to keep track of the number of elements in the array manually, using another `size` variable – theWiseBro Feb 28 '20 at 07:08
  • @theWiseBro yes I think to use one variable for storing size explicitly. This code I am using to store the vector of elements in the shared memory shared by the two processes. But using POSIX shared memory API's it's not possible to store a vector in the shared memory. So I choose vector size as "256" for the time being above, example easy purpose I gave the size as 5. – goodman Feb 28 '20 at 07:19

1 Answers1

2

You could copy by size of vector.

#include <iostream>
#include <vector>
#include <array>
#include <cstdint>
#include <limits>
#include <algorithm>

int main()
{
    std::array<std::uint32_t, 5> elem_arr ;
    std::vector<std::uint32_t> ele_vec {1,2,3};
    std::copy(ele_vec.begin(),ele_vec.end(),elem_arr.begin());
    std::vector<std::uint32_t> ele_vec_copy { elem_arr.begin() , elem_arr.begin() + ele_vec.size() };

    for(auto ele : ele_vec_copy)
        std::cout << ele << std::endl;

    return 0;
}

run online

After you edited the question

It is not possible to know how many elements used/set in std::array but this feature could be mimic by choosing a unique value which represents the element is null or not set like nullptr. But it comes with a constraint, you must not use the unique value at somewhere else in the array.

So the possible implementation is :

#include <iostream>
#include <vector>
#include <array>
#include <cstdint>
#include <limits>
#include <algorithm>
#include <limits>

std::array<std::uint32_t, 5> elem_arr;

void copy_from_vector(std::vector<std::uint32_t> elem_vec)
{
    std::copy(elem_vec.begin(),elem_vec.end(),elem_arr.begin());
}

std::vector<std::uint32_t> copy_from_array()
{
    std::vector<std::uint32_t> ele_vec_copy;
    std::copy_if( elem_arr.begin() , elem_arr.end() , 
                  std::back_inserter( ele_vec_copy ) , 
                  []( std::uint32_t val ) { 
                      return val != std::numeric_limits<std::uint32_t>::max(); 

                  } );
    return ele_vec_copy;
}

int main()
{

    elem_arr.fill( std::numeric_limits<std::uint32_t>::max() );
    std::vector<std::uint32_t> ele_vec {1,2,3};

    copy_from_vector(ele_vec);

    auto ele_vec_copy = copy_from_array();

    for(auto ele : ele_vec_copy)
        std::cout << ele << std::endl;

    return 0;
}

run online

Or store the elements as std::optional and don't copy null elements. Possible implementation is :

#include <iostream>
#include <vector>
#include <array>
#include <cstdint>
#include <limits>
#include <algorithm>
#include <limits>
#include <optional>

std::array<std::optional<std::uint32_t>, 5> elem_arr;

void copy_from_vector(std::vector<std::uint32_t> elem_vec)
{
    std::transform( elem_vec.begin() , elem_vec.end() , 
                    elem_arr.begin() ,
                    []( auto val ) { return std::optional<std::uint32_t>{ val }; }
                   );
}

std::vector<std::uint32_t> copy_from_array()
{
    std::vector<std::uint32_t> ele_vec_copy;
    std::vector<std::optional<std::uint32_t>> non_null_elements;
    std::copy_if( elem_arr.begin() , elem_arr.end() , 
                  std::back_inserter( non_null_elements ) , 
                  []( auto val ) { 
                      return val;
                  } );
    std::transform( non_null_elements.begin(), non_null_elements.end() , 
                    std::back_inserter( ele_vec_copy ) ,
                    []( auto val ) { return *val; } 
                  );
    return ele_vec_copy;
}

int main()
{
    std::vector<std::uint32_t> ele_vec {1,2,3};

    copy_from_vector(ele_vec);

    auto ele_vec_copy = copy_from_array();

    for(auto ele : ele_vec_copy)
        std::cout << ele << std::endl;

    return 0;
}

run online

calynr
  • 1,264
  • 1
  • 11
  • 23
  • Actually the code implemented in different functions. Please find the updated code. – goodman Feb 28 '20 at 05:25
  • 1
    @SwarajSomala an `std::array` has a fixed size and carries no information about how many elements were copied into it. That's why you must either use the size of the original vector or supply it by other means. – doug Feb 28 '20 at 05:30
  • 1
    @arnes thanks for your code I will try this one in my code – goodman Feb 28 '20 at 07:20
  • @SwarajSomala you're welcome. I suggest you to use `std::optional` approach, it is a bit exhaustive but states the intent clearly. – calynr Feb 28 '20 at 07:42