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);
}
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);
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.
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.
C++ is a statically-typed language. A vector will hold an object of a single type, and only a single type.
[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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With