Evg*_*eev 9 c++ map assignment-operator
这是我用来索引令牌的常用模式:检查令牌是否在地图中,如果没有,则将其添加到地图中,分配地图的大小.
在C++中执行此操作时,它会在分配之前意外地增加映射的大小:
#include <cstdio>
#include <map>
using namespace std;
int main() {
map<char, int> m;
printf("Size before adding: %d\n", m.size());
m['A'] = m.size();
printf("Size after adding: %d\n", m.size());
printf("What was added: %d\n", m['A']);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
打印出:
Size before adding: 0
Size after adding: 1
What was added: 1
Run Code Online (Sandbox Code Playgroud)
我理解它的方式,它应该评估右侧,即零,然后将其传递给将"A"和零置于地图中的函数.但它似乎是在开始分配之后对其进行评估,这没有任何意义.
在分配操作之前,不应评估右侧吗?
从迂腐的角度来说,这种行为是未指明的.
但你的情况会发生什么:
m['A'] = m.size();
Run Code Online (Sandbox Code Playgroud)
m
是std::map
它创建如果该键不存在,一个新的条目.
在您的情况下,密钥'A'
不存在,因此它创建条目,并返回对m.size()
您的情况下分配的值(默认创建)的引用.
如上所述,行为是未指定的,因为未指定操作数的评估顺序,这m.size()
可能在之前评估m['A']
.如果确实如此,那么m['A']
将是0
,不1
.
不。
(第 5.17/1 节):“在所有情况下,赋值顺序都在左右操作数的值计算之后,赋值表达式的值计算之前。”
但是请注意,虽然赋值发生在右操作数和左操作数被求值之后,但在左操作数和右操作数本身的求值之间没有指定顺序。因此,可以先评估左侧,然后评估右侧,反之亦然。