3

我有一个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

4

2 回答 2

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

如果没有分隔两个调用的序列点operator[],编译器可以自由地以它喜欢的size()任何顺序进行评估。不保证size()会在之前调用operator[]

于 2013-08-01T15:11:59.153 回答
-1

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

item->id = ids.size();
ids[item->name] = item->id;
于 2013-08-01T16:23:31.290 回答