Initilize a vector of Pair<int,int> with emplace_back - c++

I want to initialize a vector of integer pairs while specifying its size (I have to use this structure). I tried:
vector<pair<int, int>> container;
container.emplace_back(size);
And:
container.emplace_back(size, make_pair(0, 0));
But I keep having this error:
error: no matching function for call to 'std::pair<int, int>::pair(long long unsigned int&, std::pair<int, int>)'
Is there any solution or different approach?
Thank you!

emplace_back forwards its parameters to the elements constructor. std::pair<int,int> has no constructor that takes a size and a pair, hence the error. To emplace an element:
std::vector<std::pair<int, int>> container;
container.emplace_back(0,0);
However, if you want to construct a vector of certain size upfront, you need not emplace elements, because they are already there:
std::vector<std::pair<int, int>> container(size);
container[42] = make_pair(1,2); // 42 < size !

I'm guessing what you really want is something like:
vector<pair<int, int>> container(size);
This will initialize the vector constainer with size number of default-constructed elements.

Related

Is make_pair used in vector init is wrong?

I init a vector like this:
vector<pair<float,int>> A(make_pair(1.0,0),10);
and error occured:
error:no matching function for call to ‘std::vector<std::pair<float, int> >::vector(std::pair<float, int>, int)’
so how to init vector<pair> struct? I want init this with N same pairs, should i use push_back?
You have a vector of pairs. To construct one with ten pairs, you need to specify the amount first, then the initial values. In other words: "How much of what":
vector<pair<float, int>> A(10, make_pair(1.0f, 0));

Making an array of pairs of vectors

I'm trying to make an array of pairs of vectors, and in the vectors is another pair of int and float. Here is the code to help explain: pair<vector<pair<int,float> >, vector<float> >[numNodes];
At first I just had an array of a vector of pairs, but now that I changed it to an array of pairs I'm being thrown errors. I think the errors have to do with the placement of make_pair but I'm not sure.
Here is my code, but first, I little more information on what exactly I'm trying to do with the code. I'm working on a school assignment where the goal is to read in a three files of a graph and store it as an adjacency matrix and adjacency list. Right now I'm working on the list. One file has just the connections, another has the weights of the connections, and the last file has the position values of each node. Then I will search the graphs with different search algorithms. The array of vectors was the adjacency list and all the other data types involved in the pair<vector<pair<int,float> >, vector<float> >[numNodes]; were an attempt to store these variables in the list. I know another way of doing this would be to have a Node object with member variables where I can save the nodeID and position values, but I don't know exactly how this would work in terms of adding it into the list. Also would there be advantages to doing this rather than having everything stored in the list?
class AdjacencyList{
public:
pair<vector<pair<int,float> >, vector<float> > *adjList;
int numNodes;
AdjacencyList(int numNodes){//constructor
this->numNodes = numNodes;
adjList = new pair<vector<pair<int,float> >, vector<float> >[numNodes];
}
void addEdge(int sourceNode, int destNode, float weight, vector<float> posVals){
make_pair(adjList[sourceNode].push_back(make_pair(destNode, weight)), posVals);
}
}
And here is the error I'm being thrown:
main.cpp:71:39: error: no member named 'push_back' in
'std::__1::pair<std::__1::vector<std::__1::pair<int, float>,
std::__1::allocator<std::__1::pair<int, float> > >,
std::__1::vector<float, std::__1::allocator<float> > >'
make_pair(adjList[sourceNode].push_back(make_pair(destNode, weig...
Another Error I'm getting after changing the array of vectors to an array of pairs is this:
no member named 'size' in
'std::__1::pair<std::__1::vector<std::__1::pair<int, float>,
std::__1::allocator<std::__1::pair<int, float> > >,
std::__1::vector<float, std::__1::allocator<float> > >'
return adjList->size();
This size function was working before the change, which makes me think these errors are happening because its recognizing it as a pair now instead of an array. Any ideas on how to fix this?
I have no idea what vector of pairs of vectors of pairs of ints and floats and vectors of floats could possibly in any possible way represent, but anyway you could just assign to the pairs of vectors you want to assign to:
#include <vector>
class AdjacencyList{
public:
std::vector<
std::pair<
std::vector<std::pair<int,float>>,
std::vector<float>
>
> adjList;
int numNodes;
AdjacencyList(int numNodes) :
numNodes(numNodes),
// construct the vector with numNodes default-constructred elements
adjList(numNodes) {
}
void addEdge(int sourceNode, int destNode, float weight, std::vector<float> posVals){
// prefer at() instead of [] for error checking
adjList.at(sourceNode) = std::make_pair(
std::vector<std::pair<int, float>>{
// vector of pairs?? anyway:
std::make_pair(
destNode, weight
)
},
posVals
);
}
};
Do not use raw pointers - use std::vector for managing dynamic array. Your code leaks memory allocated by new.
In the first error thrown, the compiler is complaining about a missing method push_back being called. If you look at it, this makes sense because you are trying to call push_back from a pair variable (which does not have implemented any push_back method). And a similar thing goes with the second error: size() is a valid method for the vector class, but here you are calling it from a pointer pointing to an array (check this question for more info).
Instead of an array of pairs, you could use a vector of pairs, or even a set of pairs:
class AdjacencyList{
public:
vector<pair<vector<pair<int,float> >, vector<float> > > adjList;
int numNodes;
AdjacencyList(int numNodes){//constructor
this->numNodes = numNodes;
// no need to initialize the vector
//adjList = new pair<vector<pair<int,float> >, vector<float> >[numNodes];
}
void addEdge(int sourceNode, int destNode, float weight, vector<float> posVals){
// add the new pair <int, float> to the existent vector for this source node
adjList[sourceNode].first.push_back(make_pair(destNode, weight));
// define second value of the outer pair as the parameter variable posVals?
adjList[sourceNode].second = posVals;
// or you wanted to do this? I don't think so :S
make_pair(adjList[sourceNode].first, posVals);
}
}
You could do the same using an outer set instead of vector, and then you would need to change the push_back(...) for insert(...), so that you obtain the benefits of sets of pairs as well.
Actually, if you need to do it using outer arrays, then your code would be fine but changing your AddEdge function to the one proposed above.
I don't really know which is the desired performance of the code, but if you provide more information about it I might be able to help a bit more.
I think you have some inconsistencies in the type declared and the type being added.
You have declared an array (now does not matter whether it is an array, vector, or set) of pairs of vectors. Whereas on your addEdge function you are creating a pair of None (push_back returns None) and vector. The push_back on its side is adding the pair <int, float> of the first vector of the outer pair to you differently variable defined above.

Quick way to set elments of a 2D vector that is a member of class into zero

is there any quick way to make all elements of a 2D vector zero? I have the following:
`typedef class Chrom
{
vector<vector <short int>> bit;
vector<vector <float>> t1; //this is wij in the model
}
chrome ProblemConstraint;
And after resizing I make t1 as t1[Machines][Jobs]. I wonder is there any quick way that I set all elements of t1 to zero? I know there is fill but when I write
fill(ProblemConstraint.t1[0], ProblemConstraint.t1[0]+Jobs*Machines, 0);
I get error. Any help is appreciated.
As #UnholySheep commented, std::fill accepts the pair of the iterators you need to pass, not the pointer to the elements:
std::fill(ProblemConstraint.t1[0].begin(), ProblemConstraint.t1[0].end(), 0);
However, you can also initialize the values during resizing the vectors, as std::vector::resize has an overload with the element's default value:
void resize( size_type count, const value_type& value );
So, you could do:
t1[0].resize(Jobs, 0);
at the resize point.

c++ can I new a vector like this in my code into a hashmap

// father is an array of integers, irrelevant to the actual question
vector<pair<int,int>> edges = {
{0, 2},
{2, 3},
{1, 4},
{1, 5}
};
unordered_map<int, vector<pair<int,int>> edges_map_by_component;
for(auto edge: edges){
if(edges_map.find(father[edge.first]) == edges_map_by_component_map.end()){
// ---> my question is, is the following line valid?
edges_map_by_component.emplace(father[edge.first] , new vector<pair<int,int>>());
edges_map[father[edge.first]].push_back(make_pair (edge.first,edge.second));
}
}
In C++,
Can I add a vector object to the hashmap using new like this?
Is that line valid?
If yes, do I need to specify size for vectorif I instantiate it
inside the map?
Edit:
You've said I should not use new here, but seems like simply removing new is not working either. what should I do here. Basically my logic is, if the hashmap does not contain a particular key, I will create a vector of pair<int, int> for it, associate it with that key, and push_back() some pairs into the vector.
You have either a typo or a mistake in your code:
unordered_map<int, vector<pair<int,int>> edges_map_by_component;
// ^^
Should be (given you're using C++11 where you don't need to put spaces between subsequent closing template braces):
unordered_map<int, vector<pair<int,int>>> edges_map_by_component;
// ^^^
Other than that, indeed, remove new, since the second parameter of your map is vector<pair<int, int>>, not a pointer to that. That way it works fine:
#include <iostream>
#include <vector>
#include <unordered_map>
int main(void)
{
std::unordered_map<int, std::vector<std::pair<int,int> > > mymap;
mymap.emplace(5, std::vector<std::pair<int,int> >());
mymap[5].push_back({5, 7});
const std::pair<int, int> p = mymap[5].back();
std::cout << p.first << p.second;
}
The types are shown explicitly for clarity sake. A shorter way to write it would be something along the lines of:
mymap.emplace(5, decltype(mymap)::mapped_type());
One more note is that the emplace operation uses move semantics, so there is no additional copying going on, and you can construct a vector beforehand, fill it with values, and pass to emplace().
Yes usually. No not like you did because you are using the wrong type. What you are inserting here is a pointer to a vector which you haven't declared in your template parameters. You either need to change the template parameter to unsorted_map<int, vector<pair<int,int> >* > or you remove the new. This depends on how you want to use this structure later.

sort vectors in map

HOW to sort vectors inside a map based on the size of the vectors?
example:
map<int, vector<int> >
sort based on the size of the vector in order to remove some elements later within the less size.
1,2,3,4
2,5
6,7,8
after sort and delete ...
1,2,3,4
6,7,8
5
I hope this clarify the intended need.
Thanks
A map is an ordered container on which the order predicate applies to the key.
For example you can have a std::map<int, std::vector<int>, std::less<int> >
Here your key is not the vector, hence you cannot do what you are looking for with your map.
Here maybe you want a std::map<std::vector<int>, int, some_struct> where some_struct is a functor that defines a strict order relationship on your vectors.
You can do it provided the size of the vector doesn't change:
map <int, vector<int> > amap;
vector <int> v;
v.push_back( 42 );
amap.insert( make_pair( v.size(), v ));
If the size of the vector does change, you would have to remove the old entry and re-insert.