OpenCV模板化代码在派生类中产生编译错误
OpenCV templated code produces compile errors inside a Derived class
我正在制作一个应用程序,使用OpenCV为我处理一些图像。它应该允许处理不同类型的图像(由用户指定的类型)。
大多数处理都是以相同的方式进行的,并且仅取决于cv:Mat
中保存的数据的类型(用于cv::Mat.at<type>()
等函数以正确引用数据)。为此,我构建了一个基类ImageProcessor
,它将包含公共实现、需要知道类型的函数的虚拟接口和Factory方法。我进一步构建了一个模板化的DerivedTypedProcessor<datatype>
类,这样我就可以实现数据访问方法。
然而,每当我在Derived类中使用OpenCV模板化的访问函数时,我都会遇到一个奇怪的编译错误。以下是最小(非)工作示例:
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
class ImageProcessor{
public:
static ImageProcessor *NewProcessor(char option, std::string imgPath);
virtual ~ImageProcessor() {}
virtual void printMaxElem() = 0;
protected:
ImageProcessor(const std::string &imgPath) : workingImagePath(imgPath) {
this->workingImage = cv::imread(imgPath.c_str(), CV_LOAD_IMAGE_ANYDEPTH);
}
cv::Mat workingImage;
std::string workingImagePath;
};
template <typename datatype>
class TypedProcessor : public ImageProcessor{
public:
TypedProcessor(std::string imgPath) : ImageProcessor(imgPath) {}
virtual ~TypedProcessor() {}
void printMaxElem();
void preprocess();
private:
void calculateDisplayValue();
};
template <typename datatype>
void TypedProcessor<datatype>::printMaxElem(){
std::cerr << (datatype)(*std::max_element(this->workingImage.begin<datatype>(), this->workingImage.end<datatype>())) << std::endl;
}
ImageProcessor* ImageProcessor::NewProcessor(char option, std::string imgPath){
ImageProcessor *processor = NULL;
switch (option){
case 'h': // input correctly as CV_32F
processor = new TypedProcessor<float>(imgPath);
// GOAL: AVOIDING THIS:
//std::cerr << (float)(*std::max_element(processor->workingImage.begin<float>(), processor->workingImage.end<float>())) << std::endl;
break;
case 'i': // input as CV_16U but should be interpreted as CV_16S
processor = new TypedProcessor<short>(imgPath);
processor->workingImage.flags = (processor->workingImage.flags & ~CV_MAT_TYPE_MASK) | CV_16S;
// GOAL: AVOIDING THIS:
//std::cerr << (short)(*std::max_element(processor->workingImage.begin<short>(), processor->workingImage.end<short>())) << std::endl;
break;
default:
break;
}
processor->printMaxElem();
return processor;
}
int main(void){
ImageProcessor *myprocessor = ImageProcessor::NewProcessor('h', "user/will/input/this");
return 0;
}
我得到的错误是:
In member function ‘void TypedProcessor<datatype>::printMaxElem()’:
test.cpp:35:84: error: expected primary-expression before ‘>’ token
std::cerr << (datatype)(*std::max_element(this->workingImage.begin<datatype>(), this->workingImage.end<datatype>())) << std::endl;
^
test.cpp:35:86: error: expected primary-expression before ‘)’ token
std::cerr << (datatype)(*std::max_element(this->workingImage.begin<datatype>(), this->workingImage.end<datatype>())) << std::endl;
^
我还得到了this->workingImage.end<datatype>()
的等效错误。如果我用short
替换datatype
,就会出现一个非常类似的错误(而不是我想要的功能;只是为了测试目的)。变量this->workingImage
在函数内部通常是可见的(我可以在ImageProcessor
内部使用我声明为protected
的任何变量),如果我更改主体,函数调用将正常通过。
只有当我专门使用OpenCV中的任何模板访问函数(示例中的begin
和end
,at
等)时,才会出现错误
更奇怪的是,如果我取消对GOAL: AVOIDING THIS
标记的行的注释,它们会完美地编译和执行。但是,这不是一个选项,因为该结构的全部目的是避免这种情况,并通过使用模板化的Derived类来实现依赖于数据类型或特定于数据类型的函数。
注意:本示例中支持的功能和图像类型不是最终的。目前,只有两种类型的图像,但这在未来可能会改变。此外,处理功能有时会是相同的(除了需要指定不同的数据类型),有时它们会有一个共同的部分和依赖于数据/图像类型的部分(例如,预处理需要遍历所有元素,获得最小值和最大值(共同),然后对所有缺失值进行插值(对于我的CCD_ 15和CCD_。一些功能也将直接封装在基类中(如果它们不需要数据规范,例如想到图像的宽度/高度)。
有人知道如何帮助纠正代码或实现所需的功能吗?
对不起,大家,我似乎不知道如何搜索正确的问题。
在这个答案中提供了对一个较小示例的解释。显然,我需要用template
作为函数调用的前缀,它就像一个魅力。因此,有问题的函数应该重写为:
template <typename datatype>
void TypedProcessor<datatype>::printMaxElem(){
std::cerr << (datatype)(*std::max_element(this->workingImage.template begin<datatype>(), this->workingImage.template end<datatype>())) << std::endl;
}
- std::is_base_of表示ctor编译错误
- Qt5:使用QCommandLineParser类时出现奇怪的编译错误
- 如何修复sfml c++代码编译错误
- 使用 MATLAB 编码器生成C++代码:编译错误"undefined reference to `rgb2gray_tbb_real64'"
- 使用外部SDK工具链文件在VisualStudio上生成项目编译错误
- vscode下的Arduino代码出现意外编译错误
- 第三方 API 中的编译错误 - Visual Studio
- std::cout输出int时出现编译错误
- 奇怪的代码抛出编译错误模板< J,int aSize=10> C2143:语法错误:在"<"之前缺少";"
- 提升图广度优先搜索前置编译错误
- C++ 中的编译错误:未定义对"主"的引用 collect2:错误:ld 返回 1 个退出状态
- 使用带有 ref 参数的成员函数创建线程时出现编译错误
- 我在C++中遇到了这个奇怪的编译错误
- 在C++中使用 Catch 测试框架编译错误"error: expected ';' at end of declaration list"
- 使用 std::enable_if 限制派生类的模板参数时出现编译错误
- 现代OpenGL和GLEW Libraray的编译错误
- C++ 编译错误:意外的类型名称"字符串":预期的表达式
- C ++程序编译错误,找不到/访问文件
- 使用直接大括号初始化时,C++ 编译错误"声明末尾的预期";"
- 为什么传递非静态成员函数会导致编译错误?