如何在 C++ Qt 中填充静态 QMap 的值?
Posted
技术标签:
【中文标题】如何在 C++ Qt 中填充静态 QMap 的值?【英文标题】:How do I populate values of a static QMap in C++ Qt? 【发布时间】:2011-11-16 19:40:55 【问题描述】:我的 C++ 头文件中有这个:
#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
;
这是我的 C++ 源文件:
#include "LogEvent.h"
LogEvent::LogEvent()
//constructor code
//blah blah blah other functions
我想将值添加到我的静态 QMap COLUMN_NAMES。我将在哪里以及如何做到这一点?
【问题讨论】:
Qt 是时候添加一些 C++11 支持了! 【参考方案1】:同时,Qt 5.2 在 QMap 中增加了对 C++11 初始化列表的支持:
QMap::QMap(std::initializer_list<std::pair<Key, T> > list)
这意味着你可以像这样初始化你的地图:
static QMap<QString, int> my_map"a", 1, "b", 2, "c", 3;
【讨论】:
我刚刚尝试过这种方法,但它无法编译,同时所有其他 C++11 功能都可以工作...... lambdas 等,你确定它真的实现了吗?我正在使用 QT5.3.1 错误:没有匹配函数调用 'QMapCONFIG += c++11
正确启用了 C++11?
为了完整起见:如果地图已在其他地方声明,您可以使用以下内容对其进行初始化:this->m_map = QMap<QString, int>( "a", 1, "b", 2, "c", 3 );
这不是最佳方式,因为插入单对 userr1728854
提到的静态函数的方法,它只会生成一个构造函数,一个构造函数副本和一个析构函数。您可以使用返回初始化地图的静态函数:
// 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()
时被初始化,您可以预先设置文本编解码器。但这不是线程安全的。
【讨论】:
谢谢!。关于线程安全的快速问题。当你说这个函数不是线程安全的时,你的意思是如果我的应用程序是多线程的,可能会有问题正确吗? 是的,当多个线程同时执行非线程安全代码时可能会出现问题。通常,要解决此问题,您可以使用synchronization objects,如QMutex
。但在这种特殊情况下,您只需要保证只有一个线程处于活动状态时初始化静态变量,因为它不应该被修改。【参考方案3】:
另一种使用初始化列表的方法。
QMap<QString, QString> qmap_(std::map<QString, QString> "", "" );
这适用于在 Qt 被修复为直接使用初始值设定项列表之前的旧 Qt。
【讨论】:
【参考方案4】:您可以创建 std::map 并使用它来初始化 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);
另一种方法是在构造函数中初始化 COLUMN_NAMES:
LogEvent::LogEvent()
if (COLUMN_NAMES.isEmpty())
;//init it here
但这不是线程安全的,第一个方法在 main 之前调用,而第二个 during 可能在运行时调用。
【讨论】:
第一种方法应该在头文件还是源文件中?以上是关于如何在 C++ Qt 中填充静态 QMap 的值?的主要内容,如果未能解决你的问题,请参考以下文章