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?
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 T
s.*
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]>();
...