虚函数和 "no legal conversion for this pointer"
virtual function and "no legal conversion for this pointer"
我有两个 class如下。
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;
};
另一个class是来自opencv的Parallel_process。
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
有什么问题吗?
您不能在调用实例的 const
限定函数中修改实例。*)
从 Parallel_process::operator()()
中删除 const
限定符。
*) 缺少声明为可变的成员。
Parallel_process
class 继承自 cv::ParallelLoopBody
,
所以你必须覆盖
virtual void operator()(const Range& range) const
^^^^^
const
限定符意味着不能在此方法内修改任何数据成员。
NeuroShield hnn;
被调用修改
hnn.classify(vector, VECTOR_SIZE, &nm_dist, &nm_cat, &nm_nid);
因为 NeuroShield
的 classify
方法是非常量的。您可以将 classify
方法设为 const
,这样编译器就不会报错了。
第二个问题是 vector<uint16_t> dists;
。仅当向其添加 mutable
说明符时,才能通过 operator()()
修改此向量。
mutable vector<uint16_t> dists;
以上内容解释了为什么您的代码无法编译。
您代码中的主要问题是您使用 cv::ParallelLoopBody
.
的方式
正确的方法是:
准备用于存储结果的容器
通过 reference/pointer 将此容器传递给从 cv::ParallelLoopBody
派生的对象
现在 operator()() const
您可以修改 references/pointers 指向的数据
[指针不变,但指向的数据可以-这是解决你问题的关键]
所以
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
向量时,您可能应该使用一些同步方法,因为这段代码是 运行 并发的。
我有两个 class如下。
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;
};
另一个class是来自opencv的Parallel_process。
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
有什么问题吗?
您不能在调用实例的 const
限定函数中修改实例。*)
从 Parallel_process::operator()()
中删除 const
限定符。
*) 缺少声明为可变的成员。
Parallel_process
class 继承自 cv::ParallelLoopBody
,
所以你必须覆盖
virtual void operator()(const Range& range) const
^^^^^
const
限定符意味着不能在此方法内修改任何数据成员。
NeuroShield hnn;
被调用修改
hnn.classify(vector, VECTOR_SIZE, &nm_dist, &nm_cat, &nm_nid);
因为 NeuroShield
的 classify
方法是非常量的。您可以将 classify
方法设为 const
,这样编译器就不会报错了。
第二个问题是 vector<uint16_t> dists;
。仅当向其添加 mutable
说明符时,才能通过 operator()()
修改此向量。
mutable vector<uint16_t> dists;
以上内容解释了为什么您的代码无法编译。
您代码中的主要问题是您使用 cv::ParallelLoopBody
.
正确的方法是:
准备用于存储结果的容器
通过 reference/pointer 将此容器传递给从
cv::ParallelLoopBody
派生的对象
现在
operator()() const
您可以修改 references/pointers 指向的数据 [指针不变,但指向的数据可以-这是解决你问题的关键]
所以
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
向量时,您可能应该使用一些同步方法,因为这段代码是 运行 并发的。