Question

Attempting to compile the following code under Qt SDK 4.7.4 for Desktop - MinGW 4.4 results in the compiler error below:

#include <QtCore/QCoreApplication>
#include <QMap>
struct Buffer
{
   char data[4];
};
// A Bucket needs to reserve 16 chars worth of Buffers
typedef Buffer Bucket[(16 * (sizeof (char))) / (sizeof (Buffer))];
typedef QMap<QString, Bucket *> BucketMap;
int main(int argc, char *argv[])
{
   BucketMap bucket;
   bucket.insert(QString("foo"), new Bucket()); //compile error
   return 0;
}
../test/main.cpp: In function 'int main(int, char**)':
../test/main.cpp:13: error: no matching function for call to 'QMap<QString, Buffer (*)[4]>::insert(QString, Buffer*)'
../../../QtSDK/Desktop/Qt/4.7.4/mingw/include/QtCore/qmap.h:556: note: candidates are: QMap<Key, T>::iterator QMap<Key, T>::insert(const Key&, const T&) [with Key = QString, T = Buffer (*)[4]]
mingw32-make.exe[1]: *** [debug/main.o] Error 1
mingw32-make.exe: *** [debug] Error 2

I have tried converting this to an quivalent example using std::string and std::map to the same effect. I have presented the Qt version because it is more compact and ultimately the form that my project requires.
I'm guessing that I am simply missing something about how the typedef is ultimately interpreted. Why is the second argument to insert apparently a Buffer * (not Buffer(*)[4]), and how can I fix it?

Was it helpful?

Solution

Simple answer: The types don't match.

What you actually need to know: You cannot invoke a new expression for an array type. Therefore, the following two are not equivalent (and the first isn't legal):

typedef T TArr[4]; TArr * p = new TArr;  // #1

T * q = new T[4];                        // #2

The language just doesn't work that way. The second version creates a dynamic array, while the first version would like to create a single dynamic object of type "array of 4 T", which is not possible. Instead, new TArr is actually the same as new T[4], and so the result is a dynamic array of four Ts.*

You should basically just change your map's value type to either Buffer * or std::array<Buffer, 4> * or std::unique_ptr<Buffer[]> or std::unique_ptr<std::array<Buffer, 4>>, whichever you prefer.

*) This is exactly the reason why the following code is very problematic: template <T> void foo() { T * p = new T; delete p; } Imagine you say foo<int[4]>();...

OTHER TIPS

Your problem is in the typedef. Try the following:

int bs = sizeof(new Bucket);

and you will see that the value of bs is 4 (INT_PTR);

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top