std :: map []和size()的映射顺序

时间:2013-08-01 15:07:25

标签: c++ map stl

我有一个std::map并尝试用(name, id)对填充它。 id字段只是从地图的size()生成。这是一个简化版本:

#include <iostream>
#include <map>

struct A {
    std::string name;
    int id;
    A(const std::string &s) : name(s), id(-1) { }
};

class Database {
    std::map<std::string, int> ids;
public:
    void insert(A *item) {
        ids[item->name] = item->id = ids.size();
    }
    void dump() const {
        for (std::map<std::string, int>::const_iterator i = ids.begin(); i != ids.end(); i++)
            std::cout << i->second << ". " << i->first << std::endl;
    }
};

int main(int argc, char **agrv) {
    A a("Test");
    Database db;
    db.insert(&a);
    db.dump();
    return 0;
}

问题是不同的编译器对ids[item->name] = item->id = ids.size()部分的处理方式不同。 Clang ++产生

item->id = ids.size(); // First item gets 0
ids[item->name] = item->id;

当g ++做类似的事情时

ids.insert(std::pair<std::string, int>(item->name, 0));
item->id = ids.size(); // First item gets 1
ids[item->name] = item->id;

那么,这段代码是否有效(从STL角度来看)还是像i = ++i + ++i一样邪恶?

2 个答案:

答案 0 :(得分:9)

ids[item->name] = item->id = ids.size();

如果没有sequence point将两个调用分开,编译器可以按照自己喜欢的顺序自由评估operator[]size()。无法保证在size()之前调用operator[]

答案 1 :(得分:-1)

ids[item->name] = item->id = ids.size();更改为

item->id = ids.size();
ids[item->name] = item->id;
相关问题