我有一个QMap对象,我正在尝试将它的内容写入一个文件。
QMap<QString, QString> extensions;
//..
for(auto e : extensions)
{
fout << e.first << "," << e.second << '\n';
} 为什么我会得到:error: 'class QString' has no member named 'first' nor 'second'
e不是QPair类型吗
发布于 2011-12-16 10:18:34
如果您想使用first和second的STL样式,请执行以下操作:
for(auto e : extensions.toStdMap())
{
fout << e.first << "," << e.second << '\n';
}如果您想使用Qt提供的功能,请执行以下操作:
for(auto e : extensions.keys())
{
fout << e << "," << extensions.value(e) << '\n';
}发布于 2011-12-16 10:51:00
基于范围的C++11 -for使用解引用迭代器的类型作为自动推导的“光标”类型。这里,它是表达式*map.begin()的类型。
由于QMap::iterator::operator*()返回一个对值(类型为QString &)的引用,因此无法使用该方法访问该键。
您应该使用文档中描述的一种迭代器方法,但应避免使用
keys(),因为它涉及创建键列表,然后搜索每个键的值;或者,toStdMap(),因为它将所有映射元素复制到另一个映射元素而这并不是最优的。
您还可以使用包装器将QMap::iterator作为auto类型:
template<class Map>
struct RangeWrapper {
typedef typename Map::iterator MapIterator;
Map ↦
RangeWrapper(Map & map_) : map(map_) {}
struct iterator {
MapIterator mapIterator;
iterator(const MapIterator &mapIterator_): mapIterator(mapIterator_) {}
MapIterator operator*() {
return mapIterator;
}
iterator & operator++() {
++mapIterator;
return *this;
}
bool operator!=(const iterator & other) {
return this->mapIterator != other.mapIterator;
}
};
iterator begin() {
return map.begin();
}
iterator end() {
return map.end();
}
};
// Function to be able to use automatic template type deduction
template<class Map>
RangeWrapper<Map> toRange(Map & map)
{
return RangeWrapper<Map>(map);
}
// Usage code
QMap<QString, QString> extensions;
...
for(auto e : toRange(extensions)) {
fout << e.key() << "," << e.value() << '\n';
}还有另一个包装器here。
发布于 2015-07-05 09:34:30
对于对优化感兴趣的人,我尝试了几种方法,做了一些微基准测试,我可以得出结论,风格的方法比快得多。
我尝试过用以下方法添加整数:
我将它与QList/QVector的整数求和进行了比较
结果:
Reference vector : 244 ms
Reference list : 1239 ms
QMap::values() : 6504 ms
Java style iterator : 6199 ms
STL style iterator : 2343 ms感兴趣的人的代码:
#include <QDateTime>
#include <QMap>
#include <QVector>
#include <QList>
#include <QDebug>
void testQMap(){
QMap<int, int> map;
QVector<int> vec;
QList<int> list;
int nbIterations = 100;
int size = 1000000;
volatile int sum = 0;
for(int i = 0; i<size; ++i){
int randomInt = qrand()%128;
map[i] = randomInt;
vec.append(randomInt);
list.append(randomInt);
}
// Rererence vector/list
qint64 start = QDateTime::currentMSecsSinceEpoch();
for(int i = 0; i<nbIterations; ++i){
sum = 0;
for(int j : vec){
sum += j;
}
}
qint64 end = QDateTime::currentMSecsSinceEpoch();
qDebug() << "Reference vector : \t" << (end-start) << " ms";
qint64 startList = QDateTime::currentMSecsSinceEpoch();
for(int i = 0; i<nbIterations; ++i){
sum = 0;
for(int j : list){
sum += j;
}
}
qint64 endList = QDateTime::currentMSecsSinceEpoch();
qDebug() << "Reference list : \t" << (endList-startList) << " ms";
// QMap::values()
qint64 start0 = QDateTime::currentMSecsSinceEpoch();
for(int i = 0; i<nbIterations; ++i){
sum = 0;
QList<int> values = map.values();
for(int k : values){
sum += k;
}
}
qint64 end0 = QDateTime::currentMSecsSinceEpoch();
qDebug() << "QMap::values() : \t" << (end0-start0) << " ms";
// Java style iterator
qint64 start1 = QDateTime::currentMSecsSinceEpoch();
for(int i = 0; i<nbIterations; ++i){
sum = 0;
QMapIterator<int, int> it(map);
while (it.hasNext()) {
it.next();
sum += it.value();
}
}
qint64 end1 = QDateTime::currentMSecsSinceEpoch();
qDebug() << "Java style iterator : \t" << (end1-start1) << " ms";
// STL style iterator
qint64 start2 = QDateTime::currentMSecsSinceEpoch();
for(int i = 0; i<nbIterations; ++i){
sum = 0;
QMap<int, int>::const_iterator it = map.constBegin();
auto end = map.constEnd();
while (it != end) {
sum += it.value();
++it;
}
}
qint64 end2 = QDateTime::currentMSecsSinceEpoch();
qDebug() << "STL style iterator : \t" << (end2-start2) << " ms";
qint64 start3 = QDateTime::currentMSecsSinceEpoch();
for(int i = 0; i<nbIterations; ++i){
sum = 0;
auto end = map.cend();
for (auto it = map.cbegin(); it != end; ++it)
{
sum += it.value();
}
}
qint64 end3 = QDateTime::currentMSecsSinceEpoch();
qDebug() << "STL style iterator v2 : \t" << (end3-start3) << " ms";
}编辑2017年7月:我在我的新笔记本电脑(Qt 5.9,i7-7560U)上再次运行了这段代码,得到了一些有趣的变化
Reference vector : 155 ms
Reference list : 157 ms
QMap::values(): 1874 ms
Java style iterator: 1156 ms
STL style iterator: 1143 ms在这个基准测试中,STL风格和Java风格具有非常相似的性能
https://stackoverflow.com/questions/8517853
复制相似问题