I have vector
std::vector<OrderInfo *> vec
and a queue
queue<OrderInfo *> *myQueue = new queue<OrderInfo *>;
I want to copy the vector into the queue. I tried using How can I copy an entire vector into a queue? this answer and also this Insert into an STL queue using std::copy
but it's not working, how do I make it work?
this is what I tried:
myQueue = new queue(vec.begin(), vec.end());
i got
error: no matching function for call to
‘std::queue::queue(std::vector::iterator,
std::vector::iterator)’ myQueue = new
queue(vec.begin(), vec.end());
and when I tried this:
std::copy(vec.begin(),vec.end(),std::back_inserter(myQueue));
i got:
required from
‘BacStrategy::BacStrategy(EZXConnectionHandler&, const
string&, bool, const double&, int) [with Event_Type =
EZXOrderEventHandler; std::__cxx11::string =
std::__cxx11::basic_string]’
/home/yaodav/Desktop/git_repo/test/main.cpp:324:51: required from
here /usr/local/include/c++/7.4.0/bits/stl_iterator.h:490:7: error:
‘std::queue*’ is not a class, struct, or union type
operator=(const typename _Container::value_type& __value)
myQueue is a pointer, not a queue, and can’t be passed to std::back_inserter. To fix this, don’t declare it as a pointer.
Furthermore, std::back_inserter can’t be used with a std::queue, as the second link you posted explains.
Instead, simply write
std::queue<OrderInfo*> myQueue{
std::deque<OrderInfo*>(vec.begin(), vec.end())
};
If you really need a pointer, adapt the code as follows:
std::queue<OrderInfo*>* myQueue = new std::queue<OrderInfo*>{
std::deque<OrderInfo*>(vec.begin(), vec.end())
};
Lastly, if you need to fill an already initialised queue, proceed as follows: create a temporary queue using the above and assign it to your pointer:
*myQueue = std::queue<OrderInfo*>{std::deque<OrderInfo*>(vec.begin(), vec.end())};
If this looks too messy you can also create a temporary variable for that queue — but in that case you need to use std::move to ensure that the queue gets move-assigned, not expensively copied:
auto tmp = std::queue<OrderInfo*>{std::deque<OrderInfo*>(vec.begin(), vec.end())};
*myQueue = std::move(tmp);
In the same vein, consider carefully whether you want to store OrderInfos rather than pointers to OrderInfos.
Related
How can I create std::vector<T*> from std::vector<T> when copy constructor T(const T&) is deleted?
Why do I need this?
- Our threading(tbb) functor requires vector of T*.
// sample code
std::vector<T> vt;
std::vector<T*> vtp;
for (...)
{
T a;
a.build(args...); // 'build()' rebuilds the point tree
vt.push_back(a);
}
// store T pointer in vtp
for (auto i = vt.begin(); i != vt.end(); i++)
vtp.emplace_back(&*i); // error: use of deleted function 'T::T(const T&)'
Since I'm creating T object a in a loop so I can't(uniquely) store a* directly into vtp as it would be overwritten on the same address. I'm using C++11 and GCC4.8.
I've an alternative solution:
T t_a1, t_a2, t_a3, t_a4;
vtp = {&t_a1, &t_a2, &t_a3, &t_a4};
for (...)
{
(vtp[pageIdx])->build(args...); // pageIdx is block index in current range block
}
In this approach I need to build certain number of the trees in advance. Although, I can easily calculate the number of trees by getting the number of blocks in the range. But I want to avoid manual creation of the tree in advance and I'm not sure whether it would be efficient.
I have written the following code:
#include "joinCommand.h"
joinCommand::joinCommand(map<string, Task *>* threadMap) {
this->threadMap=threadMap;
}
string joinCommand::execute(vector<string> args) {
if(threadMap->count(&args.at(1)) ==1){
Task* t= this->threadMap["fkjk"];
}
}
The compiler gives an error message for the following line:
Task* t= this->threadMap["fkjk"];
The error message is:
array index is not integer.
How am I supposed to get the value of Task* from the map?
The problem here is a little subtle... threadMap is accessible by this->threadMap, but it's also a pointer. The type of this->threadMap is map<string, Task *> * not map<string, Task *>, so when you do the [] operator on it, it's acting on the pointer and not on the dereferenced object.
You would need to do this:
Task* t= (*this->threadMap)["fkjk"];
More explicitly:
Task* t= (*(this->threadMap))["fkjk"];
Alternatively you can directly call the brackets operator with the arrow syntax:
Task* t= this->threadMap->operator[]("fkjk");
As another alternative, you can use stl map's named methods instead of overloaded operators:
Task* t= this->threadMap->at("fkjk");
Read the documentation here:
http://www.cplusplus.com/reference/map/map/
This all being said and done, I suggest you use STL map's find() method to return an iterator, and check it for validity then dereference that instead, something like this:
map<string, Task*>::iterator it = this->threadMap->find(&args.at(1));
if (it != this->threadMap->end()) {
Task *t = *it; // or just directly use *it or it->
// continue to use the valid 't' pointer
}
From the first function I guess this->threadMap is a pointer because you assign another pointer to it. This guess well complies with the error message.
So the solution is to dereference the pointer before using functions from std::map:
(*this->threadMap)["fkjk"];
For some reason this isn't working for me. It gives me the vector iterator out of range error.
directory_entry TDE("Path");
vector <directory_entry> Temp;
Temp.push_back(TDE);
User_Data->DPath.insert(User_Data->DPath.begin(), Temp.begin(), Temp.end());
But, this works,
vector <directory_entry> DPath;
directory_entry TDE("Path");
vector <directory_entry> Temp;
Temp.push_back(TDE);
DPath.insert(DPath.begin(), Temp.begin(), Temp.end());
I don't think there is anything wrong with User_Data->DPath because I can push/pop and access elements in it. But for some reason I can't seam to be able to use insert on it without getting out of range errors.
Does anyone know why this might be?
edit: A popup emerges, debug assertion failed. It gives me a line in the vector header file, 1111, and a message "Expression: vector iterator out of range". If I make sure that there is at least one element in User_Data->DPath, and then start at .begin+1, I get "Expression: vector iterator+offset out of range" and it gives me line 157 of the vector header file.
edit: You are all probably right. The g_new0 function does the memory allocation http://developer.gnome.org/glib/2.32/glib-Memory-Allocation.html#g-new0
struct_type : the type of the elements to allocate. n_structs : the
number of elements to allocate. Returns : a pointer to the allocated
memory, cast to a pointer to struct_type.
typedef struct {
vector <directory_entry> DPath;
}State;
static gboolian select_dir (ClutterActor *actor, ClutterEvent *event, g_pointer data){
State *User_Data = (State*)data;
directory_entry Temp(Path);
User_Data->DPath.push_back(Temp);
...
return TRUE;
}
int main( argc, char*argv[]){
State *data = g_new0 (State, 1);
...
g_signal_connect(Cluter_Actor, "button-event", G_CALLBACK(select_dir), data)
...
clutter_main();
g_free(data);
return 0;
}
g_new0 is not a drop-in replacement for new
new does two things: allocates memory for an object, and calls the object's constructor. g_new0 only does the first, allocating memory. You need to call the object's constructor explicitly if you want to use g_new0. This is done using "placement new":
State *data = g_new0 (State, 1);
new (data) State; // placement new - calls the constructor
The reason calling State's constructor is important is that it in turn calls the constructor of the vector<directory_entry> member of State, and this is what initializes the vector. Without initializing the vector properly, you cannot use it.
Note that since you are calling the constructor explicitly, you will also need to call the destructor explicitly before freeing the memory:
data->~State(); // call destructor
g_free(data); // free the memory
Is there a reason you are using g_new0 instead of just new?
State *data = new State;
... // use data
delete data;
Hey..
I'm having trouble with some homework.
We are working on VectorList ( kinda like linked list but with vectors - don't ask why.. )
Anyway I have something like this:
#ifndef VECTORLIST_H
#define VECTORLIST_H
#include <iostream>
#include <vector>
using namespace std;
template< typename NODETYPE >
class VectorList
{
public:
VectorList(); // constructor
~VectorList(); // destructor
void insertAtFront( const NODETYPE & );
void insertAtBack( const NODETYPE & );
bool removeFromFront( NODETYPE & );
bool removeFromBack( NODETYPE & );
bool isEmpty() const;
void print() const;
private:
vector< NODETYPE > *vList; // list data as a vector
};
I need to fill in the functions.. my problem is that I do not understand how
to use STIL when I have *vList.. its a pointer to the first vector element?
// display contents of VectorList
template< typename NODETYPE >
void VectorList< NODETYPE >::print() const
{
// Fill in the missing code
}
My Idea was to use a for loop on the vector and use cout<< vector[i]<< endl;
to print the vector out..
Problem is that I get all sorts of errors and seg faults.
I do not understand how to access the vector in the function,
and how to access its elements.
This is a header file, and in the main we declare an object of VectorList<NODETYPE> IntVector...
So how can I do this?
Any help with understanding of how this *vList plays a role here would help a lot and
I'd probably be able to finish the rest..
Also, for isEmpty(), I assume I can use vList.empty().. but since vList is a pointer..
it doesn't work quite well.
== For the constructor/destructor what can I do?
I know for destructor I should iterate through the vector and use delete on each element.
But shoul
Please explain this to me, I am frustrated =[
my problem is that I do not understand how to use STL when I
have *vList.. its a pointer to the first vector element?
I assume that you are required as part of your homework to use pointer-to-vector instead of a vector itself. As a rule, I never use pointers-to-containers. In fact, the best thing that I discovered in switching from C to C++ was that I could write entire programs with no pointers at all, thanks to STL programming. Unless you are required to use pointer-to-vector, I recommend that you use the vector directly.
Certainly it is easier to use the vector proper than a pointer, but don't worry. Using the pointer isn't too bad.
First, in order to use a pointer-to-something, one must allocate the something. So, in your constructor, invoke new.
vList = new std::vector<NODETYPE>;
Anytime we invoke new, we must have a matching delete somewhere. Since our new is in our constructor, we need to invoke delete in the destructor:
delete vList;
You said:
but since vList is a pointer.. it doesn't work quite well.
Here is where life gets easy. Generally, if p is a pointer to some type, then (*p) is the object to which p points. Here are some examples:
int i = 1;
int *pInt = &i;
i = 4;
(*pInt) = 4;
std::cout << i << " " << (*pInt) << "\n";
std::vector<NODETYPE> v;
std::vector<NODETYPE> *pVector;
v.push_back();
(*pVector).push_back();
it = v.begin();
it = (*pVector).end();
So, invoking members of vList is easy : (*vList).empty().
So, your code might be :
void insertAtFront(const NODETYPE& node) { (*vList).push_front(node); }
There is a short-cut operator -> that makes the above somewhat easier to read:
void insertAtFront(const NODETYPE& node) { vList->push_front(node); }
The expression x->y is more-or-less equivalent (*x).y.
To sum up:
Allocate your vList in your constructor with new. Destroy your vList in your destructor with delete. Invoke members of vList using either (*vList).function() or vList->function().
Good luck, and come back if you have other questions!
P.s. Since you have a non-trivial destructor, you'll need to consider the rule of three.
P.P.s. You said something about iterating the vector in your destructor and deleting each of the objetcs you find there. You would only need to do that if your data type were vector-of-pointers-to-NODETYPE (contrast to what you declared: pointer-to-vector-of-NODETYPE). Until and unless you become completely comfortable with pointers, I recommend that you never store pointers in STL containers.
You should construct your object in the constructor (if you really need using bare pointers): vList = new vector< NODETYPE >();, free memory in the destructor: delete vList;, translate your methods to corresponding methods of the container class. For example, insertAtBack would be implemented as vList->push_back(elem);
How do I call a method of an object which is stored within a vector? The following code fails...
ClassA* class_derived_a = new ClassDerivedA;
ClassA* class_another_a = new ClassAnotherDerivedA;
vector<ClassA*> test_vector;
test_vector.push_back(class_derived_a);
test_vector.push_back(class_another_a);
for (vector<ClassA*>::iterator it = test_vector.begin(); it != test_vector.end(); it++)
it->printOutput();
The code retrieves the following error:
test3.cpp:47: error: request for
member ‘printOutput’ in ‘*
it.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator-> with _Iterator = ClassA**, _Container = std::vector >’, which
is of non-class type ‘ClassA*’
The problem seems to be it->printOutput(); but at the moment I don't know how to call the method properly, does anyone know?
regards mikey
The things in the vector are pointers. You need:
(*it)->printOutput();
which dereferences the iterator to get the pointer from the vector, then uses -> on the pointer to call the function. The syntax you show in your question would work if the vector contained objects rather than pointers, in which case the iterator acts like a pointer to one of those objects.
There is a Boost.PointerContainer library which could help you tremendously here.
First: it takes care of memory management, so you won't forget the release the memory pointed to.
Second: it provides a "dereferenced" interface so that you can use the iterators without the ugly patching (*it)->.
#include <boost/ptr_container/ptr_vector.hpp>
int main(int argc, char* argv[])
{
boost::ptr_vector<ClassA> vec;
vec.push_back(new DerivedA());
for (boost::ptr_vector<ClassA>::const_iterator it = vec.begin(), end = vec.end();
it != end; ++it)
it->printOutput();
}
From a Dependency Injection point of view, you might be willing to have printOutput takes a std::ostream& parameter so that you can direct it to whatever stream you want (it could perfectly default to std::cout)