我可以依靠std :: map :: operator []来触摸吗?

cp.*_*ngr 22 c++ dictionary stl c++11

我有一个C++程序,我想在其中插入缺少的任何键的默认值std::map.我认为最简单的方法是使用std::map::operator[]()类似POSIX touch命令 - 也就是说,如果值已经存在则保持不变,但如果不存在则创建它.对于例如,

#include <map>
#include <vector>
#include <iostream>

using namespace std;

int main()
{
    vector<int> keys = {0, 1};

    map<int, int> m;
    m[1] = 5;
    m[2] = 12;

    for (const int i : keys)
    {
        m[i]; // touch value
    }

    for (auto const & kv : m)
    {
        cout << kv.first << ", " << kv.second << endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

我可以确定编译器不会优化m[i];语句,因为我没有"做"任何事情吗?(没有明确指定,不读取.)

Bau*_*gen 17

是的,你可以肯定.优化调用将改变程序的可观察行为,并且不允许编译器执行此操作(RVO除外).

这被称为as -if规则.

  • @ cp.engr我仍然不喜欢在这里引用它.首先,这甚至没有触及"可观察的行为"是什么.然后,该部分只是一个"解释性脚注".最后但并非最不重要的是,我们已经对本网站上的as-if规则有一个很好的解释,我可以参考.这符合不重复答案的精神; 例如,如果标准措辞要在某些细节上进行更改,我们只需编辑一个帖子而不是进行清道夫搜索.TL; DR:报价太不完整,不值得IMO. (2认同)

Lig*_*ica 6

是的,你可以肯定.当你考虑到有问题的行等同于此时,它可能更直观:

m.operator[](i);
Run Code Online (Sandbox Code Playgroud)

...如果他们做任何事情,你不希望任何函数调用从你的程序中优化出来.


Con*_*lis 5

如果你没有为它分配一些东西,那么[]运算符确实默认构造了该键所在位置的值.

参考链接

如果k与容器中任何元素的键不匹配,则该函数将使用该键插入一个新元素,并返回对其映射值的引用.请注意,即使没有为元素指定映射值(使用其默认构造函数构造元素),这也会将容器大小增加1.