'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 &param : 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

c++


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