Почему я не могу вызвать вставку в QMap, как это? - PullRequest
0 голосов
/ 09 февраля 2012

Попытка скомпилировать следующий код в Qt SDK 4.7.4 для рабочего стола - MinGW 4.4 приводит к ошибке компилятора ниже:

#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

Я попытался преобразовать это в четырехвалентный пример, используя std::string и std::map для того же эффекта. Я представил версию Qt, потому что она является более компактной и, в конечном счете, той формой, которая требуется моему проекту.
Я предполагаю, что я просто что-то упускаю из-за того, как в конечном итоге интерпретируется typedef. Почему второй аргумент insert, по-видимому, Buffer * (не Buffer(*)[4]), и как я могу это исправить?

Ответы [ 2 ]

2 голосов
/ 09 февраля 2012

Простой ответ: типы не совпадают.

Что вам действительно нужно знать: вы не можете вызвать выражение new для типа массива.Следовательно, следующие два не эквивалентны (и первый не является законным):

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

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

Язык просто не работает таким образом.Вторая версия создает динамический массив, в то время как первая версия хотела бы создать один динамический объект типа «массив из 4 T», что невозможно.Вместо этого new TArr фактически совпадает с new T[4], и в результате получается динамический массив из четырех T с. *

Вы должны просто изменить значение вашей картывведите либо Buffer *, либо std::array<Buffer, 4> *, либо std::unique_ptr<Buffer[]>, либо std::unique_ptr<std::array<Buffer, 4>>, в зависимости от того, что вы предпочитаете.

*) Именно поэтому следующий код очень проблематичен: template <T> void foo() { T * p = new T; delete p; }Представь, что ты говоришь foo<int[4]>(); ...

1 голос
/ 09 февраля 2012

Ваша проблема в typedef. Попробуйте следующее:

int bs = sizeof(new Bucket);

и вы увидите, что значение bs равно 4 (INT_PTR);

...