如果我做:
std::map<string, size_t> word_count;
size_t value = word_count.count("a") == 0 ? 1 : 2;
word_count["a"] = value;
Run Code Online (Sandbox Code Playgroud)
那么word_count ["a"]的最终值是1,正如我所料.如果相反,我做:
std::map<string, size_t> word_count;
word_count["a"] = word_count.count("a") == 0 ? 1 : 2;
Run Code Online (Sandbox Code Playgroud)
那么word_count ["a"]的最终值是2.为什么!?
chr*_*ris 10
正式地,可以首先评估任务的任何一方.由实现来决定哪个.如果word_count不包含"a",则插入一个,并返回对它的左值引用.如果word_count确实包含一个,则只发生后一个部分.尽管首先评估哪一方的不确定性,您可以遵循可能的执行:
operator[]插入元素,因为它不存在.count()找到它并返回1,因此最终为它赋值为2.
operator[]返回现有元素并count()找到它并返回1,因此最终为它赋值为2.
count()返回0,所以你从右边得到1.然后,"a"插入到地图中并赋值为1.
count()返回1,所以从右侧得到2.然后,word_count["a"]访问并分配2.
简而言之,你不能依靠它来做你想做的事情,所以最好使用你可以依赖的东西.mrfontanini提出了一个很好的建议,所以我会稍微编辑一下:
word_count["a"]++;
word_count["a"] = std::min(word_count["a"], 2);
Run Code Online (Sandbox Code Playgroud)
第一行确保它被插入并且值至少为1.在重复执行此操作的情况下,第二行将该值限制为最大值2.
我的答案基于两件事:
当选择要评估的一侧时,必须在另一侧开始之前评估整个侧面.
构造如word_count["a"] = 1展示明确定义的行为,即使在插入元素然后分配元素的情况下也是如此.
下面有一些关于这些是否属实的辩论和讨论.我现在变得更加正式了.
看着这一行:
word_count["a"] = word_count.count("a") == 0 ? 1 : 2;
Run Code Online (Sandbox Code Playgroud)
我相信如果word_count["a"]在执行该行之前地图中不存在,则会导致未定义的行为。
这是因为word_count["a"]如果一个条目不存在,将在地图中创建一个条目,这将改变word_count.count("a"). 我们也不需要在这两个调用之间进行排序。