'C++ loop using queue- error: ‘begin’ was not declared in this scope
I am not very familiar with C++ pointer and address. I think I have an error related to the pointers. The program consists of different objects of objects, I will describe the related part below.
I have multiple users managed by a “JobManager” class, the users are stored in queue. Each user has two queues of type “JobQueue” and has a procedure returns an object of type “Mqueue”, this procedure gets the Mqueue object by accessing the object (JobQueue seqjobs;). The JobQueue class contains two Mqueues of type <Job*> and other procedures. The Job class is a normal class describe each job. The related parts in Job, JobManager, User, JobQueue and Mqueue classes are presented below.
The Job class:
class Job {
public:
std::string accname, peer;
int ra = 0;
paramlist params;
JobState state = WAITING;
std::chrono::system_clock::time_point jobarrivingtime;
bool error = false;
int jobno = -1;
Job(AccJob accjob, std::string peer) {
jobarrivingtime = (high_resolution_clock::now());
accname = accjob.accname();
this->peer = peer;
this->ra =accjob.ra();
for (auto ¶m : accjob.parameters())
params[param.first] = param.second;
}
Job() {}
};
The JobManager class:
class JobManager {
public:
std::deque<User*> users;
void addJob(Job* job) {
for (User *user : users) {
if (user->peername == job->peer) {
if(job->ra == 1 || job->ra == 2)
user->ranjobs.pushJob(job);
else if (job->ra == 3 || job->ra == 4)
user->seqjobs.pushJob(job);
return;
}
}
User *user = new User();
user->peername = job->peer;
if(job->ra == 1 || job->ra == 2)
user->ranjobs.pushJob(job);
else if (job->ra == 3 || job->ra == 4)
user->seqjobs.pushJob(job);
users.push_back(user);
}
.
.
.
.
};
In User class:
class User {
public:
JobQueue seqjobs;
JobQueue ranjobs;
std::string peername;
MQueue<Job*>* getSeqMemJobs(){
return &(seqjobs.memjobs);
}
};
The JobQueue class:
class JobQueue {
public:
MQueue<Job*> comjobs;
MQueue<Job*> memjobs;
bool isEmpty() {
return (memjobs.empty() && comjobs.empty());
}
Job* peekComJob() {
Job* j = comjobs.peek();
return j;
}
.
.
.
.
.
};
The MQueue class:
#include <mutex>
#include <queue>
template <class T>
class MQueue {
public:
MQueue(){
}
void push(T a) {
std::lock_guard<std::mutex> lock(mutex);
data.push(a);
}
bool empty() {
return data.empty();
}
T peek() {
std::lock_guard<std::mutex> lock(mutex);
return data.front();
}
T pop() {
std::lock_guard<std::mutex> lock(mutex);
T ret = data.front();
data.pop();
return ret;
}
private:
std::queue<T> data;
std::mutex mutex;
};
What is the problem?
I have an error when I try to access some jobs in each user. To simplify the problem, I am trying to access one Mqueue for each user by using “user->getSeqMemJobs()”. I have two loops; one to access all users and one to access each user jobs in the memJobs Mqueue that in seqjobs JobQueue . The first loop works fine, but I have error in the second loop.
In the main (the error in the second loop):
for (User *user : jobmanager.users) {
std::cout << " - " << user->peername << std::endl;
for (Job *job : user->getSeqMemJobs())
std::cout << " - " << job->accname << std::endl;
}
The error:
daemon/cserv.cpp:533:47: error: ‘begin’ was not declared in this scope
for (Job *job : user->getSeqMemJobs())
^
daemon/cserv.cpp:533:47: note: suggested alternatives:
In file included from /usr/include/c++/7/string:51:0,
from /usr/include/c++/7/bits/locale_classes.h:40,
from /usr/include/c++/7/bits/ios_base.h:41,
from /usr/include/c++/7/ios:42,
from /usr/include/c++/7/ostream:38,
from /usr/include/c++/7/iostream:39,
from daemon/cserv.cpp:2:
/usr/include/c++/7/bits/range_access.h:105:37: note: ‘std::begin’
template<typename _Tp> const _Tp* begin(const valarray<_Tp>&);
^~~~~
/usr/include/c++/7/bits/range_access.h:105:37: note: ‘std::begin’
/usr/include/c++/7/bits/range_access.h:105:37: note: ‘std::begin’
daemon/cserv.cpp:533:47: error: ‘end’ was not declared in this scope
for (Job *job : user->getSeqMemJobs())
^
daemon/cserv.cpp:533:47: note: suggested alternatives:
In file included from /usr/include/c++/7/string:51:0,
from /usr/include/c++/7/bits/locale_classes.h:40,
from /usr/include/c++/7/bits/ios_base.h:41,
from /usr/include/c++/7/ios:42,
from /usr/include/c++/7/ostream:38,
from /usr/include/c++/7/iostream:39,
from daemon/cserv.cpp:2:
/usr/include/c++/7/bits/range_access.h:107:37: note: ‘std::end’
template<typename _Tp> const _Tp* end(const valarray<_Tp>&);
^~~
/usr/include/c++/7/bits/range_access.h:107:37: note: ‘std::end’
/usr/include/c++/7/bits/range_access.h:107:37: note: ‘std::end’
I know the loops cannot access pointer, but what can I do here? I think the iterator is already implemented in "queue" class which used in MQueue class.
Update I added begin and end to MQueue class (as below) but it wasn't working, maybe I did it in a wrong way.
T begin(){
return data.front();
}
T end(){
return data.back();
}
Also, I modified the for loop to be: (I think it's more promising)
for (User *user : jobmanager.users) {
std::cout << " - " << user->peername << std::endl;
for (Job *job :std::begin(user->getSeqMemJobs())){
std::cout << " - " << job->accname << std::endl;
if (job == std::end(user->getSeqMemJobs()))
break;
}
}
Then I got this error:
daemon/cserv.cpp: In member function ‘void DaemonImpl::executor()’:
daemon/cserv.cpp:533:58: error: no matching function for call to ‘begin(MQueue<Job*>*)’
for (Job *job :std::begin(user->getSeqMemJobs())){
^
In file included from /usr/include/c++/7/bits/range_access.h:36:0,
from /usr/include/c++/7/string:51,
from /usr/include/c++/7/bits/locale_classes.h:40,
from /usr/include/c++/7/bits/ios_base.h:41,
from /usr/include/c++/7/ios:42,
from /usr/include/c++/7/ostream:38,
from /usr/include/c++/7/iostream:39,
from daemon/cserv.cpp:2:
/usr/include/c++/7/initializer_list:89:5: note: candidate: template<class _Tp> constexpr const _Tp* std::begin(std::initializer_list<_Tp>)
begin(initializer_list<_Tp> __ils) noexcept
^~~~~
/usr/include/c++/7/initializer_list:89:5: note: template argument deduction/substitution failed:
daemon/cserv.cpp:533:58: note: mismatched types ‘std::initializer_list<_Tp>’ and ‘MQueue<Job*>*’
for (Job *job :std::begin(user->getSeqMemJobs())){
^
In file included from /usr/include/c++/7/string:51:0,
from /usr/include/c++/7/bits/locale_classes.h:40,
from /usr/include/c++/7/bits/ios_base.h:41,
from /usr/include/c++/7/ios:42,
from /usr/include/c++/7/ostream:38,
from /usr/include/c++/7/iostream:39,
from daemon/cserv.cpp:2:
/usr/include/c++/7/bits/range_access.h:48:5: note: candidate: template<class _Container> constexpr decltype (__cont.begin()) std::begin(_Container&)
begin(_Container& __cont) -> decltype(__cont.begin())
^~~~~
/usr/include/c++/7/bits/range_access.h:48:5: note: template argument deduction/substitution failed:
/usr/include/c++/7/bits/range_access.h: In substitution of ‘template<class _Container> constexpr decltype (__cont.begin()) std::begin(_Container&) [with _Container = MQueue<Job*>*]’:
daemon/cserv.cpp:533:58: required from here
/usr/include/c++/7/bits/range_access.h:48:50: error: request for member ‘begin’ in ‘__cont’, which is of pointer type ‘MQueue<Job*>*’ (maybe you meant to use ‘->’ ?)
begin(_Container& __cont) -> decltype(__cont.begin())
~~~~~~~^~~~~
/usr/include/c++/7/bits/range_access.h:58:5: note: candidate: template<class _Container> constexpr decltype (__cont.begin()) std::begin(const _Container&)
begin(const _Container& __cont) -> decltype(__cont.begin())
^~~~~
/usr/include/c++/7/bits/range_access.h:58:5: note: template argument deduction/substitution failed:
/usr/include/c++/7/bits/range_access.h: In substitution of ‘template<class _Container> constexpr decltype (__cont.begin()) std::begin(const _Container&) [with _Container = MQueue<Job*>*]’:
daemon/cserv.cpp:533:58: required from here
/usr/include/c++/7/bits/range_access.h:58:56: error: request for member ‘begin’ in ‘__cont’, which is of pointer type ‘MQueue<Job*>* const’ (maybe you meant to use ‘->’ ?)
begin(const _Container& __cont) -> decltype(__cont.begin())
~~~~~~~^~~~~
/usr/include/c++/7/bits/range_access.h:87:5: note: candidate: template<class _Tp, long unsigned int _Nm> constexpr _Tp* std::begin(_Tp (&)[_Nm])
begin(_Tp (&__arr)[_Nm])
^~~~~
/usr/include/c++/7/bits/range_access.h:87:5: note: template argument deduction/substitution failed:
daemon/cserv.cpp:533:58: note: mismatched types ‘_Tp [_Nm]’ and ‘MQueue<Job*>*’
for (Job *job :std::begin(user->getSeqMemJobs())){
^
Thanks
Solution 1:[1]
Solved by adding a iterator pointer in MQueue as:
T begin(){
return data.front();
}
T end(){
return data.back();
}
T next(){
ptr = ptr + (sizeof(T));
return *ptr;
}
void resetPtr(){
ptr = &data.front();
}
Modify the loop in the main as below:
for (User *user : jobmanager.users) {
std::cout << " - " << user->peername << std::endl;
Job* job;
job = user->getSeqMemJobs()->begin();
while(job != NULL){
std::cout << " - " << job->accname << std::endl;
if (job == user->getSeqMemJobs()->end())
break;
job = user->getSeqMemJobs()->next();
}
user->getSeqMemJobs()->resetPtr();
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Shaden |
