1

I am developing a project in C++ with Qt and OpenCV 3.0. When trying to use the face recognition module of OpenCV, I get an error.

When accessing the file predict_collector.hpp and the class below

class CV_EXPORTS_W PredictCollector {
protected:
    ...
public:
    ...
    CV_WRAP virtual bool emit(const int label, const double dist, const int state = 0); 
};

The compiler links the emit keyword with its definition in Qt, generating this error:

\libs\opencv3.0.0\opencv_contrib-master\modules\face\include\opencv2\face/predict_collector.hpp(77): error C2059: syntax error: 'const'

because 'const'is a keyword in C++ and cannot be passed an argument to the Qt emit function. You see that the compiler treats emit as if it is the Qt version.

Noting that emit is a macro function, it is not an ordinary one, so we cannot use namespaces, a you can see in qobjectsdef.h:

#ifndef QT_NO_EMIT
# define emit
#endif

I tried to make

#undef emit 

in the file predict_collector.hpp but it will generate errors in all of the project.

How to resolve this issue?

ProEns08
  • 1,856
  • 2
  • 22
  • 38
  • In the docs they say "called with every recognition result", so your problem is when you recognize a face? Can you also add the error message? You can ask the question on [opencv forum](http://answers.opencv.org/questions) – sop Jan 13 '16 at 12:21
  • I added the error message, thanks. – ProEns08 Jan 13 '16 at 12:45
  • [OT]: the `const` for `emit` arguments are useless. – Jarod42 Jan 13 '16 at 13:02

4 Answers4

2

Use namespace calls in your code. That allows you to write namespace1::functionX() and namespace2::functionX().

Where that is not possible try adding in

namespace namespace1{
    //code here
}

or

using namespace
//Code here//

If using these in your own code doesn't fix the error then it may be possible to add this into the relevant OpenCV and Qt files.

Flash_Steel
  • 606
  • 1
  • 6
  • 16
2

The solution that worked for me is to reorder the order of my included files.

I put the #include <opencv2/face.hpp> before any call to any Qt include file. so that the emit keyword will not be defined yet.

And Recursively, if your header containing #include <opencv2/face.hpp> is included in another header file in your project, be careful to put it before any Qt include file, and the same for the second file.


The important is to make sure to call #include <opencv2/face.hpp> before any call to to the definition of the Qt macro emit. You will be sure that your code will be compiled without any collision.

ProEns08
  • 1,856
  • 2
  • 22
  • 38
  • maybe you could add a little note [here](https://github.com/Itseez/opencv_contrib) , so @comDiv knows, that emit is causing trouble – berak Jan 14 '16 at 09:29
2

See: https://stackoverflow.com/a/22190519/355177

In short:

You can define the QT_NO_KEYWORDS macro, that disables the “signals” and “slots” macros.

If you use QMake:

CONFIG += no_keywords

If you’re using another build system, do whatever it needs to pass -DQT_NO_KEYWORDS to the compiler.

If you want to use Qt "emit" use Q_EMIT.

Community
  • 1
  • 1
firescreamer
  • 620
  • 8
  • 20
  • Yes, very informative, but the solution I put is easier and did not need to make many changes to the code,+1 Thanks. – ProEns08 Jan 13 '16 at 15:27
1

That is indeed one of the issues of defining macros (and especially unprefixed macros, the macro in QT should indeed have been defined as QT_EMIT or similar to minimize collisions).

What you will most likely need to do is to undefine the macro before including the OpenCV headed, and then define it back. And also do the same on every place the emit is called.

Namespaces will not likely help here, as the macro "emit" will still be defined and will still clash with the function name.

Something like this:

#ifdef emit
// undef and store emit
#define MY_EMIT_STORE emit
#undef emit
#endif

#include "predict_collector.hpp"

#ifdef MY_EMIT_STORE
// return emit back for QT
#define emit MY_EMIT_STORE
#undef MY_EMIT_STORE
#endif

and on every place emit is called. The need to return emit back can be avoided, if you include all QT headers before the OpenCV headers and if you do not use the QT emit in your cpp. Then just undefining the emit macro could work:

// include all QT headers

#ifdef emit
#undef emit
#endif

#include "predict_collector.hpp"

// do not use the QT emit below

Another option (based on your last edit) might be to define the QT_NO_EMIT macro so that the emit will not be defined by QT, before including the QT headers, like:

#define QT_NO_EMIT
// include the QT headers

Or by defining QT_NO_EMIT generally in your compiler flags ("-DQT_NO_EMIT").

EmDroid
  • 5,918
  • 18
  • 18
  • Your advises are very informative. You point me to the real location of the problem, it helps me a lot but it did not solve me the problem, so I cannot tick your answer, +1 for your help. I will describe the solution that worked for me in an independent answer, – ProEns08 Jan 13 '16 at 13:10