使用BGSLibrary示例代码在VS2012中编译报C2864错误求助
问题背景
我在Windows 10系统上,搭配OpenCV 3.0和Visual Studio 2012尝试运行BGSLibrary的示例代码时,编译阶段遇到了几个报错,具体情况如下:
示例代码
#include <iostream> #include <cv.h> #include <highgui.h> #include "package_bgs\bgslibrary.h" #include "package_bgs\FrameDifference.h" int main(int argc, char **argv) { CvCapture *capture = 0; capture = cvCaptureFromCAM(0); if(!capture){ std::cerr << "Cannot initialize video!" << std::endl; return -1; } IBGS *bgs; bgs = new FrameDifference; IplImage *frame; while(1) { frame = cvQueryFrame(capture); if(!frame) break; cv::Mat img_input = cv::cvarrToMat(frame); cv::imshow("Input", img_input); cv::Mat img_mask; cv::Mat img_bkgmodel; // by default, it shows automatically the foreground mask image bgs->process(img_input, img_mask, img_bkgmodel); //if(!img_mask.empty()) // cv::imshow("Foreground", img_mask); // do something if(cvWaitKey(33) >= 0) break; } delete bgs; cvDestroyAllWindows(); cvReleaseCapture(&capture); return 0; }
编译错误信息
1 error C2864: 'bgslibrary::algorithms::IBGS::firstTime' : only static const integral data members can be initialized within a class
2 error C2864: 'bgslibrary::algorithms::IBGS::showOutput' : only static const integral data members can be initialized within a class
5 error C2864: 'bgslibrary::algorithms::IBGS::firstTime' : only static const integral data members can be initialized within a class
16 IntelliSense: data member initializer is not allowed c:\Users\izzaa\Documents\Visual Studio 2012\Projects\Project1_bgslibrary\Project1_bgslibrary\package_bgs\CodeBook.h 48
17 IntelliSense: data member initializer is not allowed c:\Users\izzaa\Documents\Visual Studio 2012\Projects\Project1_bgslibrary\Project1_bgslibrary\package_bgs\CodeBook.h 49
解决方案
别担心,这些错误的根源很明确:Visual Studio 2012默认使用的是C03标准,而BGSLibrary的代码大概率是基于C11及以后的标准编写的——C03不允许在类内部直接初始化非静态、非const的成员变量,而C11及以后支持这个特性。咱们可以通过以下几种方式解决:
1. 切换项目的C++标准版本
首先尝试最简单的方法:给VS2012项目开启C++11支持:
- 右键项目 -> 选择「属性」
- 依次展开「配置属性」->「C/C++」->「语言」
- 找到「C标准」选项,选择「ISO C11 标准(/std:c++11)」
- 点击「确定」后重新编译项目
注意:VS2012对C++11的支持是不完全的,如果这个选项不存在或者修改后还是报错,就需要用下面的方法手动修改代码。
2. 手动修改BGSLibrary的头文件
直接修改报错的头文件,把类内的成员变量初始化移到构造函数的初始化列表中:
- 打开
IBGS.h,找到类似这样的代码:
修改为:class IBGS { private: bool firstTime = true; bool showOutput = true; // ...其他成员 };class IBGS { private: bool firstTime; bool showOutput; // ...其他成员 public: // 在构造函数初始化列表中初始化成员 IBGS() : firstTime(true), showOutput(true) {} // ...其他已有的构造函数和方法 }; - 同样处理
CodeBook.h第48、49行的成员变量,把类内直接初始化的代码移到CodeBook类的构造函数中,比如把int someVar = 0;改成在构造函数里写someVar(0)。
3. 统一使用OpenCV的C++接口优化代码
你的代码混合了OpenCV的C接口(CvCapture、cvQueryFrame)和C接口(cv::Mat),虽然OpenCV3.0还兼容C接口,但统一用C接口会更稳定,也能避免一些潜在问题。修改后的代码片段如下:
// 替换原来的CvCapture部分 cv::VideoCapture capture(0); if(!capture.isOpened()){ std::cerr << "Cannot initialize video!" << std::endl; return -1; } cv::Mat frame; // 替换while循环的读取逻辑 while(capture.read(frame)) { cv::imshow("Input", frame); cv::Mat img_mask, img_bkgmodel; bgs->process(frame, img_mask, img_bkgmodel); if(cv::waitKey(33) >= 0) break; } // 释放资源的代码也可以简化 delete bgs; cv::destroyAllWindows(); // VideoCapture会自动释放资源,无需手动调用release
内容的提问来源于stack exchange,提问作者Izza Aditya

