Pointer to a multidimensional vector - c++

I am trying to initialize a pointer (*vectorName) with a 2D vector 366 by 4.
Both
vector<int> *vectorName = new vector<int>(366, new vector<int>(4));
and
vector<int> *vectorName = new vector<int>(366, vector<int>(4));
do not work and give me the error
Error: no instance of constructor "std::vector, <_Ty, _Alloc>::vector [with_ty=int, _Alloc=std_allocator]"
argument types are (const int, std::vector>*)
What can I do?
This is happening within the main function.

vector<int> *vectorName = new vector<int>(366, vector<int>(4));
The above doesn't work because the vector constructor template (ignoring a few things) looks as follows:
vector <TYPE> (SIZE, variable of type TYPE);
And in vector<int>(366, vector<int>(4)), vector <int> (4) is not of type int.
To create a vector with 366 elements that are vector of ints of size 4:
vector<vector<int> > *vectorName = new vector<vector<int> >(366, vector<int>(4));
or, if you don't need a pointer: (which you quite possibly don't)
vector<vector<int> > vectorName(366, vector<int>(4));
As a side note, if it's a fixed size 2D vector, why are you using vector, and not just an array. This would be much simpler:
int arr[366][4];

I assume that you're trying to use a pointer to a vector in order to get a dynamic C-array of vectors. There's no reason to do that. You can use a vector of vectors instead:
vector< vector<int> >
You can initialize that like this:
vector< vector<int> > vec(4);
for (size_t i = 0; i < 4; ++i) {
vec[i].resize(366);
}
Usage example:
vec[3][365] = 3;
If however you really do want a pointer to such a vector:
vector< vector<int> >* vec = new vector< vector<int> >(4);
for (size_t i = 0; i < 4; ++i) {
(*vec)[i].resize(366);
}
(*vec)[3][365] = 3;
If your size is constant and you're using a C++11 compiler, you can use an easier way, std::array:
array<array<int, 366>, 4> arr;
// Usage example
arr[3][365] = 3;
Or a pointer to a dynamically allocated one:
array<array<int, 366>, 4>* arr = new array<array<int, 366>, 4>;
// Usage example
(*arr)[3][365] = 3;

Are you trying to do this? This makes a 2D vector of vectors with int. It creates 366 vectors with a vector with size 4,where all items are initialized to zero. Now you have a 2D vector of 366 by 4.
vector<vector<int> > twod( 366, vector<int>(4,0));
and if you would like a pointer to this vector:
vector<vector<int> >* twodptr = &twod;
if you would really need this.

Related

Derefrencing an iterator to 2D vector and assigning its value to another 2D vector

I have a 2D vector vector<vector<int> > det; and I want to assign the last value or the most recently push_back'd value to another 2D vector v. This is what I tried v = *(det.rbegin()); but it shows an error. What is the correct way of doing it ?
error message : conversion from 'std::vector' to non-scalar type 'std::vector >' requested
The last entry of your 2D array is not a 2D array, i.e. of type vector < vector < int > >, but of type vector < int > .
As such it cannot be assigned to another variable of type
vector < vector < int > >
This works fine:
#include<iostream>
#include<vector>
int main(){
std::vector<std::vector<int> > det, det2;
std::vector<int> vector1, vector2, vector3;
vector1.push_back(3);
vector1.push_back(4);
vector1.push_back(5);
vector2.push_back(13);
vector2.push_back(14);
vector2.push_back(15);
vector3.push_back(113);
vector3.push_back(114);
vector3.push_back(115);
std::vector<int> member_of_2darray;
det.push_back(vector1);
det.push_back(vector2);
det.push_back(vector3);
det2.push_back(det.back());
std::cout<<det2[0][2]<<std::endl; // returns 115
//last:element
std::cout<<det.back().back()<<std::endl;
}
edit: if you deperately want to use iterators: here is an working example:
#include<iostream>
#include<vector>
int main(){
std::vector<std::vector<int> > det, det2;
std::vector<int> vector1, vector2, vector3;
std::vector<std::vector<int> >::iterator it;
vector1.push_back(3);
vector1.push_back(4);
vector1.push_back(5);
vector2.push_back(13);
vector2.push_back(14);
vector2.push_back(15);
vector3.push_back(113);
vector3.push_back(114);
vector3.push_back(115);
std::vector<int> member_of_2darray;
det.push_back(vector1);
det.push_back(vector2);
det.push_back(vector3);
it = det.end();
det2.push_back(*(it-1));
std::cout<<det2[0][2]<<std::endl; //output: 115
}

Can i push an array of int to a C++ vector?

Is there any problem with my code ?
std::vector<int[2]> weights;
int weight[2] = {1,2};
weights.push_back(weight);
It can't be compiled, please help to explain why:
no matching function for call to ‘std::vector<int [2], std::allocator<int [2]> >::push_back(int*&)’
The reason arrays cannot be used in STL containers is because it requires the type to be copy constructible and assignable (also move constructible in c++11). For example, you cannot do the following with arrays:
int a[10];
int b[10];
a = b; // Will not work!
Because arrays do not satisfy the requirements, they cannot be used. However, if you really need to use an array (which probably is not the case), you can add it as a member of a class like so:
struct A { int weight[2];};
std::vector<A> v;
However, it probably would be better if you used an std::vector or std::array.
You cant do that simply.
It's better you use either of these:
vector <vector<int>> (it's basically a two dimensional vector.It should work in your case)
vector< string > (string is an array of characters ,so you require a type cast later.It can be easily.).
you can declare an structure (say S) having array of int type within it i.e.
struct S{int a[num]} ,then declare vector of
vector< S>
So indirectly, you are pushing array into a vector.
Array can be added to container like this too.
int arr[] = {16,2,77,29};
std::vector<int> myvec (arr, arr + sizeof(arr) / sizeof(int) );
Hope this helps someone.
Arrays aren't copy constructable so you can't store them in containers (vector in this case). You can store a nested vector or in C++11 a std::array.
You should use std::array instead of simple array:
#include <vector>
#include <array>
std::vector<std::array<int, 2>> weights;
std::array<int, 2> weight = {1, 2};
weights.push_back(weight);
or with a constructor:
std::vector<std::array<int, 2>> weights;
weights.push_back(std::array<int, 2> ({1, 2});
One possible solution is:
std::vector<int*> weights;
int* weight = new int[2];
weight[0] =1; weight[1] =2;
weights.push_back(weight);
Just use
vector<int*> .That will definitely work.
A relevant discussion on the same topic : Pushing an array into a vector
Situation like:
int arr[3] = { 1, 2, 3 };
std::vector<int[]> v;
v.push_back(arr);
doesn't work with error "cannot initialize array in vector with .."
This, could be worked well
int * arr = new int[3] { 1, 2, 3 };
std::vector<int*> v;
v.push_back(arr);
To instantiate the vector, you need to supply a type, but int[2] is not a type, it's a declaration.

Multi-dimensional vector initialization

I have following std::vector declaration:
std::vector<std::vector<std::vector<int> > > m_input;
I am initializing it as follows:
m_input.resize (100);
m_output.resize(100);
for (int i = 0; i < 100; ++i) {
m_input [i].resize(100);
m_output[i].resize(100);
for (int j = 0; j < 100; ++j){
m_input [i][j].resize(100);
m_output[i][j].resize(100);
}
}
How can I achieve this via the member initializer list?
std::vector<T> has a constructor that takes two arguments, a number of elements and an initial value. In your case, you want to initialize m_input with 100 copies of a std::vector<std::vector<int> > , so it'd be : m_input(100, X). Now, that X in turn is a vector of 100 std::vector<int>, which in turn contains a hundred ints:
: m_input(100, std::vector<std::vector<int> >(100, std::vector<int>(100, 0)))
my_class::my_class()
: m_input(100, std::vector< std::vector<int> >(100, std::vector<int>(100) ))
{
}
That said, implementing a multi-dimensional field should be done by projecting into a one-dimensional one, as Viktor said in his comment to the question.
If you can assert that your vector dimensions are going to be of a fixed length, then why not use std::array?
For example:
std:array<std::array<std::array<int, 100>, 100>, 100>
That way you can take advantage of all the memory being contiguously allocated (as hinted at by Viktor_Sehr in the comments), without the added implementation woes of accessing a 1-dimensional array in a 3-dimensional way.

Declaring Dynamic 2D Vector in class

We're trying to use a 2D vector because we want a 2D array that will grow dynamically.
We tried this:
In the class declaration:
vector<vector<double> > table;
But then table doesn't seem to be allocated. We get a segfault when we try to access members.
So then we tried this:
Class Declaration:
vector<vector<double> >* table;
Constructor:
table = new vector<vector<double> >;
But now we the way we accessed it before (with [][]) doesn't work.
We tried a dummy class with this:
class myClass {
public:
myClass();
~myClass();
vector<vector<double> > t;
};
myClass::myClass()
{
t = vector<vector<double> > (10, vector<double>(10));
}
But it wouldn't free properly and we got core dumps. Also when we tried to grow the array, we'd have expclitly construct each new row.
Ex:
t[50] = vector<double>(5);
t[50][10] = 10;
If we didn't do it like this, we'd get a segfault
You'll need to resize the tables before you access elements.
vector<vector<double> > table;
table.resize(10);
for (int i = 0; i < 10; ++i)
table[i].resize(20);
Make sure your vectors are large enough to store your elements. If a vector t has size N, the last element you can access is t[N-1].
t = vector<vector<double> > (10, vector<double>(10));
t[50] = vector<double>(5); // This is wrong! Vector size is 10, you access 50th.
t[50][10] = 10; // Wrong again! Vector size 5, you access 10th.
If you have Boost installed try using Boost Multi-array.
You can access the element in [][] manner by derefrencing.
Vector<vector<double>> *table ;
table = new vector<vector<double>> ( n, vector<double>( m, 0.0)) ;
cout << (*table)[i][j] ;
Most of the times, this works perfectly well.

how to convert int to vector<int>?

When I assign int to vector I get an error says "conversion from 'int' to non-scalar type 'std::vector<int, std::allocator<int> >' requested", what should I do?
I have vector varr(4, -1); what is the right way to do "varr[2] = 3"?
They're two different types. If you want to add an int to a vector<int> do something like:
std::vector<int> vec;
vec.push_back(10);
Update: To set an element within the vector:
std::vector<int> vec(16, 0); // Create a 16 element vector containing all 0's
vec[4] = 10; // Sets the 5th element (0 based arrays) to 10
There appears to be a thorough codeguru tutorial which might be of interest.
A vector is a collection of ints. You can not assign an int to the collection, you add it to the collection using the push_back() function:
std::vector<int> manyInts;
int oneInt = 42;
manyInts.push_back(oneInt);
If you want to add the int to to a vector<int> you should use push_back:
vector<int> v;
int i = 5;
v.push_back(i);
int sum = 468;
vector<int> v;
while(sum!=0){
v.push_back(sum%10);
sum /= 10;
}
reverse(v.begin(), v.end());