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

ura*_*nix 3 c++ stl map

我有一个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;
}
Run Code Online (Sandbox Code Playgroud)

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

item->id = ids.size(); // First item gets 0
ids[item->name] = item->id;
Run Code Online (Sandbox Code Playgroud)

当g ++做类似的事情

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

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

Joh*_*ica 9

ids[item->name] = item->id = ids.size();
Run Code Online (Sandbox Code Playgroud)

如果没有将两个调用分开的序列点,编译器可以自由评估operator[]并按size()任何顺序进行评估.size()以前无法保证会被调用operator[].

  • 并回答他的最后一个问题:代码是有效的,但部分行为未指定.(它并不像`i = ++ i + ++ i`那样邪恶.) (2认同)
  • 序列点是如此2003年.现在我们已经*排序 - 在排序关系之前...这个例子是*不确定地排序*,但是`i = ++ i + ++ i`是*未经测序*因此更邪恶 (2认同)