dimanche 23 octobre 2016

std::vector::erase on a class resulting in compiler error

I wrote a multi-threading program for multiple strips of Adafruit LEDs. But the issue is with the erasure of Thread objects from the threads vector. I researched this for hours to no avail.

For some reason when I compile the code it does not like the threads.erase() function, regardless of whether I pass an iterator or an iterator added to an int.

Thanks in advance.

Threads are stored in the std::vector

I get this error:

In file included from /tmp/arduino_build_577097/sketch/lib/Command.h:5:0,
                 from /tmp/arduino_build_577097/sketch/lib/Command.cpp:1,
                 from /home/michael/Arduino/dorm-leds/dorm-leds.ino:17:
/home/michael/Arduino/libraries/StandardCplusplus/vector: In instantiation of 'T* std::vector<T, Allocator>::erase(std::vector<T, Allocator>::iterator) [with T = Thread; Allocator = std::allocator<Thread>; std::vector<T, Allocator>::iterator = Thread*]':
/tmp/arduino_build_577097/sketch/lib/ThreadHandler.cpp:36:37:   required from here
/home/michael/Arduino/libraries/StandardCplusplus/vector:315:13: error: use of deleted function 'Thread& Thread::operator=(const Thread&)'
     data[i] = data[i+1];
             ^
In file included from /tmp/arduino_build_577097/sketch/lib/Thread.cpp:1:0,
                 from /home/michael/Arduino/dorm-leds/dorm-leds.ino:18:
/tmp/arduino_build_577097/sketch/lib/Thread.h:6:7: note: 'Thread& Thread::operator=(const Thread&)' is implicitly deleted because the default definition would be ill-formed:
 class Thread {
       ^
/tmp/arduino_build_577097/sketch/lib/Thread.h:6:7: error: non-static reference member 'Command& Thread::cmd', can't use default assignment operator

Thread.h contains:

#ifndef Thread_H
#define Thread_H

#include "Command.h"

class Thread {
  unsigned int id;
  Command& cmd;
  unsigned long int updateRate;
  unsigned long int timeSum;
public:
  Thread(unsigned int id, Command& cmd, unsigned long int t);
  ~Thread();
  unsigned int getID();
  Command& getCMD();
  unsigned long int getUpdateRate();
  unsigned long int getTimeSum();
  void addTimeSum(unsigned int dT);
  void zeroTimeSum();
};

#endif

Thread.cpp contains:

#include "Thread.h"

//<<constructor>>
Thread::Thread(unsigned int id, Command& cmd, unsigned long int t){
  this->id = id;
  this->cmd = cmd;
  this->updateRate = t;
  this->timeSum = t;
}

//<<destructor>>
Thread::~Thread(){}

// get this thread ID
unsigned int Thread::getID(){
  return this->id;
}

// get the command that this thread contains
Command& Thread::getCMD(){
  return this->cmd;
}

// get the update rate
unsigned long int Thread::getUpdateRate(){
  return this->updateRate;
}

// get the current time sum
unsigned long int Thread::getTimeSum(){
  return this->timeSum;
}

// add to the time sum
void Thread::addTimeSum(unsigned int dT){
  this->timeSum += dT;
}

// set the time sum back down to zero
void Thread::zeroTimeSum(){
  this->timeSum = 0;
}

ThreadHandler.h contains:

#ifndef ThreadHandler_H
#define ThreadHandler_H

#include <StandardCplusplus.h>
#include <vector>
#include <Arduino.h>
#include "Strip.h"
#include "Command.h"
#include "Thread.h"

class ThreadHandler {
    std::vector<Thread> threads;
    short int** strip_status;
    unsigned int elapsed_time;
    unsigned int next_id;
public:
    ThreadHandler();
    ~ThreadHandler();
    std::vector<Thread> listThreads();
    void queue(Command& cmd, unsigned long int dU);
    void updateTimeAccumulated(unsigned long int dT);
    void executeTick();
private:
    bool conflicts(Strip*, Strip*);
};

#endif

The important (erroring) part of ThreadHandler.cpp:

// queue a command
void ThreadHandler::queue(Command& cmd, unsigned long int dU){
    int i = 0;
    for(std::vector<Thread>::iterator it = threads.begin(); it != threads.end(); it++, i++){
        Thread this_thread = *it;

        if(conflicts(cmd.getDependencies(), this_thread.getCMD().getDependencies())){
            // de-queue any conflicting commands
            threads.erase(threads.begin() + i); // this line errors
            //threads.erase(it) also errors
        }
    }

    // queue this command as a new thread (set current time as the update rate so it initially sets on start)
    Thread t = Thread(next_id, cmd, dU);

    next_id++;

    threads.push_back(t);
}

Aucun commentaire:

Enregistrer un commentaire