C++, with vector<int[2]> can I push_back({someNum1,someNum2})? - c++

I have the vector:
vector<int[2]> storeInventory; //storeInventory[INDEX#]{ITEMNUM, QUANTITY}
and I am wanting to use the push_back() method to add new arrays to the inventory vector. Something similar to this:
const int ORANGE = 100001;
const int GRAPE = 100002
storeInventory.push_back({GRAPE,24});
storeInventory.push_back{ORANGE, 30};
However, when I try using the syntax as I have above I get the error Error: excpeted an expression. Is what I am trying just not possible, or am I just going about it the wrong way?

Built-in arrays are not Assignable or CopyConstructible. This violates container element requirements (at least for C++03 and earlier). In other words, you can't have std::vector of int[2] elements. You have to wrap your array type to satisfy the above requirements.
As it has already been suggested, std::array in a perfect candidate for a wrapper type in C++11. Or you can just do
struct Int2 {
int a[2];
};
and use std::vector<Int2>.

I don't believe it's possible to pass arrays like that. Consider using std::array instead:
vector<std::array<int, 2> > storeInventory;
storeInventory.push_back({{GRAPE,24}});

If it's only vector of int[2] you could use:
std::vector<std::pair<int, int>> vec
Adding elements:
int a, b;
vec.push_back(std::make_pair(a, b));

storeInventory.push_back({GRAPE, 24});
storeInventory.push_back({ORANGE, 30});
You can try this. I think you forgot parentheses.

C-style arrays are not copyable, so can't be used as the element type in a std::vector.

Simply use a std::vector<int *> :)

Related

Initializing an array of vector

I am trying to initialize an array of a vector of ints.
This is my code:
vector<int> *vec[] = new vector<int>[n+1];
I get the following compilation error:
initialization with '{...}' expected for aggregate object
What's wrong with this ?
If you need an array (in the broad sense) of elements of type vector<int>, I advise you to use:
std::vector<std::vector<int>> vec(n+1);
vec will be a vector of vectors. The number of vectors will be n+1 like it seems you wanted. std::vector will manage the memory for you, so there's no need for new/delete.
In C++ we also have std::array, but it looks like the number of elements in vec is dynamically dependant on n, which makes a topmost std::vector the proper fit.
There are many advantages using C++ std::vector/std::array over C style arrays. See e.g. the answers here: std::vector versus std::array in C++.
If you must use a C style topmost array, see the other answer.
The problem is that you're trying to initialize an array of pointers to vector with a "pointer to a vector".
To solve this you can either remove the [] from the left hand side of the declaration or not mix std::vector and raw pointers.
//--------------v----------------------->removed [] from here
vector<int> *vec = new vector<int>[n+1];

std::tuple vs std::array as items of a std::vector

I have this case:
std::vector<4_integers> v;
What would fit best here?
std::tuple solution:
std::vector<std::tuple<int,int,int,int>> v;
std::array solution:
std::vector<std::array<int,4>> v;
and why?
EDIT (The use case):
Sorry for not mentioning that before. I am going to use it as follow:
for(const auto& item:v){
some_function(item[0],item[1],item[2],item[3]); // or tuple equivalent
}
Of course I need to keep them stored because computing the 4 integers is not a thing that I want to repeat again and again.
For this specific case, I'd have to disagree with the comments. For homogeneous type containers - as is the case here (all ints) - array is superior.
When looking at the interface of std::tuple vs. std::array, it is very clear that the latter is a container (with iterators, e.g.), while the former is not. This means that the rest of the standard library will be much more naturally applicable to the latter.
If the types weren't homogeneous, there wouldn't be a question - it would have to be std::tuple.
This depends a lot on the use case, but if the elements are somehow related, I would choose array. You can iterate over array and use std algorithms with them.
I usually think tuple as a substitute to something you could replace with a struct like:
struct fourIntegers{
int int1;
int int2;
int int3;
int int4;
};
Sometimes the tuple is just more compact/clear than a new struct.

vector argument in c++ class

I would like to create a C++ Class which takes a "vector" int t[9] as argument. I don't understand why my code isn't working :
Here is the content of the header :
class Matrice3x3{
public:
int n;
int t[9];
Matrice3x3 inverse();
float det();
void print();
Matrice3x3(int u = 3);
Matrice3x3(int p[9], int m = 9);
private:
};
And here the content of the class description :
Matrice3x3::Matrice3x3(int u) {
n = u*u;
}
Matrice3x3::Matrice3x3(int p[9] , int m){
n = m;
t = p;
}
And i get this error :
In constructor 'Matrice3x3::Matrice3x3(int*, int)':
incompatible types in assignment of 'int*' to 'int [9]'
t = p;
^
I just don't see where i said one of the [] was a pointer...
thanks for answering!
You cannot copy arrays like this. You should copy them element by element or use memcpy.
In general case it is better to use standard library for containers (std::vector in this case). You should have strong reason to prefer C-style array to standard container.
Well, if you really want fixed sized arrays, use C++11's std::array<> (Boost has a definition as well, for pre C++11). You can allocate it as std::array < int, 9 > and then pass it around as an object. You can also use the size() member function to get the number of elements (although its hardcoded in the type) and it has other member functions (such as begin() and end()) which make it look like a std container, so you can use std's algorithms on it as well. Basically, a wrapper around a fixed sized array. Of course you can pass by value of reference.

c++ map containing a list

I would like to create a map where the key is an int, and the value is a list of arrays (int[][]).
I tried this :
const int R = 4, C = 5;
std::map<int, std::list<int[R][C]> > s;
but it won't compile and I don't understand why ... (R and C are parameter of the program but do not change during execution).
Arrays are not copy constructable or copy assignable, which an element of a standard container must be. Your code will compile as is, but the array type breaks the requirements for the standard containers and you'll run into undefined behaviour. You can't have an std::list<int[R][C]>. However, C++11 provides a nice new compile-time constant sized std::array for your pleasure:
typedef std::array<std::array<int, C>, R> array_2d;
typedef std::list<array_2d> array_list;
std::map<int, array_list> s;
Otherwise, other alternatives are to use std::vector instead of std::array (preferred), or to have a std::list of int** and dynamically allocate your 2D arrays.
However, I'd consider a bit of a rethink of your design. Is this really the structure you want? Should any of the data be grouped into a struct?

How can I convert different numeric vector type in C++

My question is related to numeric type conversion in C++. A very common way to do that is to use static_cast, for example:
float a;
int b;
a = 3.14;
b = static_cast<int>(a);
Then, how about numeric vector type conversion? Could we continue to use static_cast? I have done the following experiment:
typedef vector<int> IntVector;
typedef vector<float> FloatVector;
IntVector myvector;
myvector.push_back(3);
myvector.push_back(4);
myvector.push_back(5);
// Solution 1 (successful)
FloatVector solution1 ( myvector.begin(), myvector.end() );
for(int i=0; i<solution1.size(); i++)
cout<<solution1[i]<<endl;
// Solution 2 (failed)
FloatVector solution2;
solution2 = static_cast<FloatVector> (myvector);
It seems that for numeric vector types it is impossible to use static_cast to convert. I was wondering whether there are good solutions to this problem. Thanks!
You can use std::copy, as it performs sequential assignement.
The language directly supports conversion from one numeric type to another. You do not even need the static_cast, you could just assign. This conversion involves a logical copying of the value, as opposed to a reinterpretation of the value representation.
The language does not directly support conversion between arrays of different types, or for that matter of std::vector of different types.
But as you found, there is some support for copying elements, and then when each element is numeric, the built-in support for numeric type conversion kicks in for each element.
You can neither assign nor cast a container with a template parameter T (std::vector<int>) into another with a template parameter L (std::vector<float>). They are different classes after all.
However, since they use iterators you can fill your FloatVector with std::copy:
FloatVector solution2(myvector.size());
std::copy(myvector.begin(),myvector.end(),solution2.begin());
Edit to address your comment:
If your current function signature is f(FloatVector) I would recommend you to change it to
template< class T >
ReturnType f(std::vector<T> myVector, ....);