виртуальная функция и «нет легального преобразования для этого указателя» - PullRequest
0 голосов
/ 08 ноября 2018

У меня есть два класса следующим образом.

class NeuroShield
{
public:

    NeuroShield();
    uint16_t begin();

    void setNcr(uint16_t value);
    uint16_t getNcr();
    void setComp(uint8_t value);
    uint8_t getComp();
    void setLastComp(uint8_t value);
    void setIndexComp(uint16_t value);
    uint16_t getDist();
    void setCat(uint16_t value);
    uint16_t getCat();
    void setAif(uint16_t value);
    uint16_t getAif();
    void setMinif(uint16_t value);
    uint16_t getMinif();
    void setMaxif(uint16_t value);
    uint16_t getMaxif();
    uint16_t getNid();
    void setGcr(uint16_t value);
    uint16_t getGcr();
    void resetChain();
    void setNsr(uint16_t value);
    uint16_t getNsr();
    uint16_t getNcount();
    void setPowerSave();
    void forget();
    void forget(uint16_t maxif);

    void countTotalNeurons();
    void clearNeurons();

    void setContext(uint8_t context);
    void setContext(uint8_t context, uint16_t minif, uint16_t maxif);
    void getContext(uint8_t* context, uint16_t* minif, uint16_t* maxif);
    void setRbfClassifier();
    void setKnnClassifier();

    uint16_t broadcast(uint8_t vector[], uint16_t length);
    uint16_t learn(uint8_t vector[], uint16_t length, uint16_t category);
    uint16_t classify(uint8_t vector[], uint16_t length);
    uint16_t classify(uint8_t vector[], uint16_t length, uint16_t* distance, uint16_t* category, uint16_t* nid);
    uint16_t classify(uint8_t vector[], uint16_t length, uint16_t k, uint16_t distance[], uint16_t category[], uint16_t nid[]);

    void readNeuron(uint16_t nid, uint16_t model[], uint16_t* ncr, uint16_t* aif, uint16_t* cat);
    void readNeuron(uint16_t nid, uint16_t nuerons[]);
    uint16_t readNeurons(uint16_t neurons[]);
    void readCompVector(uint16_t* data, uint16_t size);
    void writeNeurons(uint16_t neurons[], uint16_t ncount);
    void writeCompVector(uint16_t* data, uint16_t size);

    uint16_t testCommand(uint8_t read_write, uint8_t reg, uint16_t data);

    uint16_t fpgaVersion();
    void nm500Reset();
    void ledSelect(uint8_t data);

    uint16_t total_neurons;

private:
    uint16_t support_burst_read = 0;
};

Другой класс - это Parallel_process из opencv.

class Parallel_process : public cv::ParallelLoopBody
{

private:
    Mat gray_img;
    Mat orig_img;
    int size;
    int row;
    NeuroShield hnn;
    vector<uint16_t> dists;
public:
    uint16_t nm_cat, nm_nid;
    Parallel_process(Mat inputImgage, Mat orgImg, int row_, NeuroShield &hnn_) : gray_img(inputImgage), row(row_), hnn(hnn_){}

    virtual void operator()(const Range& range) const
    {
        for (int col = range.start; col < range.end; col = col +2)
        {
            uint8_t vector[NEURON_SIZE];
            Mat roi_img = gray_img(Rect(col, row, size, size));
            Mat res;
            resize(roi_img, res, Size(16, 16), 0, 0, INTER_LINEAR);
            uint8_t* data = (uint8_t*)res.data;
            for (int j = 0; j < VECTOR_SIZE; j++)
                vector[j] = *data++;
            uint16_t nm_dist;
            hnn.classify(vector, VECTOR_SIZE, &nm_dist, &nm_cat, &nm_nid);
            dists.push_back(nm_dist);

        }
    }
};

В основной функции параллельный процесс называется

cv::parallel_for_(cv::Range(0, 8), Parallel_process(inputImgage, orgImg, row_, hnn, dists_))

Но у меня есть две ошибки компиляции в следующих двух строках.

hnn.classify(vector, VECTOR_SIZE, &nm_dist, &nm_cat, &nm_nid);
dists.push_back(nm_dist);

Ошибки

Error   C2663   'NeuroShield::classify': 3 overloads have no legal conversion for 'this' pointer    
Error   C2663   'std::vector<uint16_t,std::allocator<_Ty>>::push_back': 2 overloads have no legal conversion for 'this' pointer 

Что может быть не так?

Ответы [ 2 ]

0 голосов
/ 08 ноября 2018

Parallel_process класс наследуется от cv::ParallelLoopBody, поэтому вы должны переопределить

virtual void operator()(const Range& range) const
                                            ^^^^^

const квалификатор подразумевает, что никакие элементы данных не могут быть изменены внутри этого метода.

NeuroShield hnn;

модифицируется звонком

hnn.classify(vector, VECTOR_SIZE, &nm_dist, &nm_cat, &nm_nid);

потому что classify метод NeuroShield неконстантный. Вы можете сделать метод classify как const, тогда компилятор не будет жаловаться. Вторая проблема с vector<uint16_t> dists;. Этот вектор можно изменить с помощью operator()(), только если вы добавите к нему спецификатор mutable.

mutable vector<uint16_t> dists;

Все выше объясняет, почему ваш код не компилируется. Основной проблемой в вашем коде является то, как вы используете cv::ParallelLoopBody.

Правильный путь:

  1. подготовить контейнеры, в которых будут храниться результаты

  2. передать эти контейнеры по ссылке / указателю на объект, полученный из cv::ParallelLoopBody

  3. теперь в operator()() const вы можете изменять данные, указанные ссылками / указателями [указатели не изменены, но точные данные могут быть - это ключ к решению вашей проблемы]

Итак

int size;
int row;
NeuroShield& hnn; // make reference 
vector<uint16_t>& dists; // make reference

т е р:

Parallel_process(Mat inputImgage, Mat orgImg, int row_, NeuroShield &hnn_, vector<uint16_t>& vec) : 
gray_img(inputImgage), 
row(row_), 
hnn(hnn_),
dists(vec) {}

теперь эти строки

   hnn.classify(vector, VECTOR_SIZE, &nm_dist, &nm_cat, &nm_nid);
   dists.push_back(nm_dist);

должно работать. Возможно, вам нужен какой-то метод синхронизации при доступе к вектору dists, потому что этот код выполняется одновременно.

0 голосов
/ 08 ноября 2018

Вы не можете изменить экземпляр внутри const -квалифицированной функции, вызвавшей его. *)

Снять const -кавалификатор с Parallel_process::operator()().

*) за исключением членов, объявленных изменяемыми.

...