Qi W.
Qi W.

Reputation: 786

QString and some Qt classes are recognized as incomplete types

My code looks like this:

a.h

#include <QString>

namespace foo {
  QString bar(QString a);
}

a.cc

#include "a.h"

namespace foo {
  QString bar(QString a) { return QString(); } 
}

The issue is in a.cc, QString might be taken as foo::QString, thus results in incomplete type compilation error, 'cause we didn't and never want to define a QString class in foo namespace.

Note that I have CMakeLists.txt containing below lines:

set(CMAKE_AUTOMOC ON)
find_package(Qt5 COMPONENTS widgets REQUIRED)
set(Qt_LIBRARIES Qt5::Widgets)
target_link_libraries(a Qt_LIBRARIES)

Any idea? Thanks!


Kuba Ober have pointed my problem exactly.

Actually I have a header file with 500 lines code. Say a.h looks like this

a.h

Note that the braces for foo is not closed. While due to too much lines and the compiler (VS2013) doesn't complaint it with red underscores, I just didn't detect it.

Then in a.cc, we have code like this
a.cc

'Cause we include a.h in a.cc, even the std is wrapped under the suri namespace. Thus the QString might be wrapped under suri too, resulting in recognized as incomplete type compilation error.

This is the whole story. Thank you, guys!

Upvotes: 0

Views: 4495

Answers (1)

The code you show is correct. The following demonstrates that there's no problem with such code. According to the standard, there's no way QString used here would be ambiguous: there's only one namespace visible from each point of use where that identifier exists.

// main.cpp
#include <QString>

namespace foo {
  QString bar(QString a);
  QString bar(QString) { return QString(); }
}

int main() {}

Whatever is the source of your problem, it isn't what you're showing to us. At the very least, you have a mistake somewhere that declares a foo::QString identifier, or declares QString in another visible namespace and makes the lookup ambiguous. Perhaps you even suffer from the most vexing parse, but in reverse (you meant a function, but got a member named QString instead)?

A bug that reproduces a similar problem reads:

// main.cpp
#include <QString>

namespace foo {
  QString bar(QString a);
  int QString(); // BUG: introduce foo::QString as an identifier

  // Doesn't compile since QString is ambiguous
  QString bar(QString) { return QString(); }
  // Compiles OK, indicates presence of the BUG
  ::QString bar(::QString) { return ::QString(); }
}

int main() {}

You could also be inadvertently wrapping Qt includes into a namespace, e.g. on my particular platform (OS X 10.9), the following code produces the exact same error as you see:

#include <cstddef>
#include <cstring>
#include <cstdint>
#include <algorithm>
#include <string>
using namespace std;
class QString;
namespace z {
#include <QString>
}

namespace foo {
  QString bar(QString a);
  QString bar(QString) { return QString(); }
}

int main() {}

Compiler output:

../test2/main.cpp:15:11: error: incomplete result type 'QString' in function definition
  QString bar(QString) { return QString(); }
          ^
../test2/main.cpp:8:7: note: forward declaration of 'QString'
class QString;
      ^
../test2/main.cpp:15:22: error: variable has incomplete type 'QString'
  QString bar(QString) { return QString(); }
                     ^
../test2/main.cpp:8:7: note: forward declaration of 'QString'
class QString;
      ^
../test2/main.cpp:15:33: error: invalid use of incomplete type 'QString'
  QString bar(QString) { return QString(); }
                                ^~~~~~~~~
../test2/main.cpp:8:7: note: forward declaration of 'QString'
class QString;
      ^
3 errors generated.

Upvotes: 2

Related Questions