Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use a vector wrapper class when enclosed in another vector?

Consider a free function from a third part library that expects a std::vector as argument: void foo( std::vector<sometype>& );

Now, I write a wrapper around this type so I can add member functions. To be able to use foo() with that type, I add an access function.

class Wrapper
{
   private:
      std::vector<sometype> _data;
   public:
       std::vector<sometype>& data() { return _data; }
       const std::vector<sometype>& data() const { return _data; }
       //... other stuff
};

This way, I can still use foo():

Wrapper a;
foo( a.data() );

But now consider another function, that expects a vector of vectors of sometype (edit: and that adds elements into that vector) :

void bar( std::vector<std::vector<sometype>>& );

But the datatype I have is std::vector<Wrapper> vec;

Is there any way to use my wrapper type to call bar() ? What I want to do is this:

 std::vector<Wrapper> vec;
 bar( ??? );

The point I want to avoid is first call bar() with the required type, and then having to copy one by one the elements into my vector<Wrapper>.

At first, I'd say "No", but maybe there is some smart solution ?

Edit2: to give an example, consider the following toy implementation for bar() with an int root datatype:

void bar( std::vector<std::vector<int>>& vv )
{
   std::vector<int> v1 = { 1,2,3 };
   std::vector<int> v2 = { 4,5,6 };
   vv.push_back(v1);
   vv.push_back(v2);
}
like image 521
kebs Avatar asked May 12 '15 09:05

kebs


People also ask

How do you push a vector into another vector?

Appending a vector elements to another vector To insert/append a vector's elements to another vector, we use vector::insert() function. Syntax: //inserting elements from other containers vector::insert(iterator position, iterator start_position, iterator end_position);

How do you combine two vectors?

The concatenation of vectors can be done by using combination function c. For example, if we have three vectors x, y, z then the concatenation of these vectors can be done as c(x,y,z). Also, we can concatenate different types of vectors at the same time using the same same function.

Can you push back a vector into a vector C++?

Insertion in Vector of VectorsElements can be inserted into a vector using the push_back() function of C++ STL. Below example demonstrates the insertion operation in a vector of vectors. The code creates a 2D vector by using the push_back() function and then displays the matrix.

Can a vector hold different data types in C++?

C++ is a statically-typed language. A vector will hold an object of a single type, and only a single type.


1 Answers

[Edited after new comments requiring elements added in the bar function] A possible solution would be to keep a std::vector<std::vector<sometype>> for the function to use and just operate on a VectorAccessor object referring to the real vectors

#include <iostream>
#include <vector>

struct sometype {
    int value;
    sometype(int v) : value(v) {}
};

void bar(std::vector<std::vector<sometype>>& par) {

    std::cout << "bar() - Before adding new elements:" << std::endl;
    for (auto& subvec : par) {
        std::cout << "Subvector: {";
        for (auto& sometypeItem : subvec) {
            std::cout << sometypeItem.value << " ";
        }
        std::cout << "};" << std::endl;
    }

    std::vector<sometype> newItem = {32, 33};
    par.emplace_back(newItem);

}

class VectorAccessor {
    std::vector<std::vector<sometype>>& m_vec;
public:
    VectorAccessor(std::vector<std::vector<sometype>>& v) : m_vec(v) {}

    template<typename V>
    void addVector(V&& vec) {
        static_assert(std::is_same<typename std::remove_reference<V>::type, 
            std::vector<sometype>>::value, "Not the right type");
        m_vec.emplace_back(std::forward<V>(vec));
    }

    std::vector<sometype> accessVector(size_t index) {
        return m_vec[index];
    }
};

int main(int argc, char ** argv)
{

    std::vector<std::vector<sometype>> vec;
    VectorAccessor vAcc(vec);


    // Add an element through the vector accessor
    std::vector<sometype> firstVector = {42};
    firstVector.emplace_back(52);
    vAcc.addVector(firstVector);

    // Call bar and add a few elements
    bar(vec);

    // Now access stuff with the usual wrapper
    std::cout << "Elements added by bar:" << std::endl;
    std::cout << "Subvector: {";
    for (auto& sometypeItem : vAcc.accessVector(1)) {
        std::cout << sometypeItem.value << " ";
    }
    std::cout << "};" << std::endl;

    return 0;
}

Example

like image 135
Marco A. Avatar answered Oct 01 '22 09:10

Marco A.