Подтвердить что ты не робот

Как заполнить значения статического QMap в С++ Qt?

У меня это в моем заголовочном файле С++:

#include <QMap>
#include <QString>

class LogEvent {

public:
    LogEvent();

    enum column_t {TIMESTAMP_COLUMN = 0, TYPE_COLUMN = 1, EVENT_COLUMN = 2,
        FILE_COLUMN = 3};
    static QMap<column_t, QString> COLUMN_NAMES;

    static QMap<column_t, QString> getColumnNames() {
        return LogEvent::COLUMN_NAMES;
    }

    //blah blah blah other functions
};

Это мой исходный файл на С++:

#include "LogEvent.h"

LogEvent::LogEvent()
{
    //constructor code
}

//blah blah blah other functions

Я хочу добавить значения в мой статический QMap COLUMN_NAMES. Где и как я могу это сделать?

4b9b3361

Ответ 1

Вы можете использовать статическую функцию, которая возвращает инициализированную карту:

// source file:
QMap<column_t, QString> LogEvent::initColumnNames() {
    QMap<column_t, QString> map;
    map.insert(LogEvent::TIMESTAMP_COLUMN,"Timestamp");
    // and so on
    return map;
}

QMap<column_t, QString> LogEvent::COLUMN_NAMES = initColumnNames();

Кроме того, в случае, если вы хотите использовать интернационализацию строк в статических переменных и сначала нужно вызвать QTextCodec::setCodecForTr, рекомендуется переместить статическую переменную в ее функцию getter:

class LogEvent {

public:
// ...
    static QMap<column_t, QString> initColumnNames();

    static QMap<column_t, QString> getColumnNames() {
        static QMap<column_t, QString> COLUMN_NAMES = initColumnNames();
        return COLUMN_NAMES;
    }
}

Этот способ COLUMN_NAMES будет инициализирован первым вызовом getColumnNames(), и вы можете заранее установить текстовый кодек. Но это не является потокобезопасным.

Ответ 2

Тем временем Qt 5.2 добавила поддержку списков инициализаторов С++ 11 в QMap:

QMap::​QMap(std::initializer_list<std::pair<Key, T> > list)

Это означает, что вы можете инициализировать свою карту следующим образом:

static QMap<QString, int> my_map{{"a", 1}, {"b", 2}, {"c", 3}};

Ответ 3

Другой подход, использующий список инициализаторов.

QMap<QString, QString> qmap_(std::map<QString, QString> {{ "", "" }});

Это работает для более ранних Qt, прежде чем Qt был исправлен для работы с списками инициализаторов напрямую.

Ответ 4

Вы можете создать std:: map и использовать его для init QMap или просто заменить QMap на std:: map:

 static const std::pair<T1, T2> arr[] = { 
     std::pair<T1, T2>(v1, v2),
     std::pair<T1, T2>(v3, v4),
};

static std::map<T1, T2> my_map(arr, arr + sizeof(arr) / sizeof(arr[0]));
QMap<column_t, QString> LogEvent::COLUMN_NAMES(my_map);

Другим способом является init COLUMN_NAMES в конструкторе:

LogEvent::LogEvent() {
   if (COLUMN_NAMES.isEmpty())
     ;//init it here

но это не является потокобезопасным, первый метод был вызван до main, а второй во время может быть вызван во время выполнения.