当前位置: 首页 > 知识库问答 >
问题:

在地图中分配值时,正确的计算顺序是什么?

巫马英豪
2023-03-14

我知道编译器通常是代码中错误的最后一个罪魁祸首,但对于以下C代码(从实际项目中提炼出来)的以下行为,我看不到任何其他解释:

#include <iostream>
#include <map>

int main()
{
    auto values = { 1, 3, 5 };
    std::map<int, int> valMap;

    for (auto const & val : values) {
        std::cout << "before assignment: valMap.size() = " << valMap.size();
        valMap[val] = valMap.size();
        std::cout << " -> set valMap[" << val << "] to " << valMap[val] << "\n";
    }
}

此代码的预期输出为:

before assignment: valMap.size() = 0 -> set valMap[1] to 0
before assignment: valMap.size() = 1 -> set valMap[3] to 1
before assignment: valMap.size() = 2 -> set valMap[5] to 2

但是,当我使用(默认)C 14编译器构建发布版本时,输出变为:

before assignment: valMap.size() = 0 -> set valMap[1] to 1
before assignment: valMap.size() = 1 -> set valMap[3] to 2
before assignment: valMap.size() = 2 -> set valMap[5] to 3

换句话说,valMap中的所有值都比它们应该的值大1-它看起来像是在赋值的右侧被计算之前附加的映射。

这只发生在具有C 14语言标准的版本构建中(这是VS2019中的默认值)。调试构建工作正常(我讨厌这种情况发生——我花了几个小时才知道发生了什么),就像C 17和C 20的发布构建一样。这就是为什么它在我看来像一只虫子。

我的问题是:这是一个编译器错误,还是我使用做了一些错误/危险的事情。作业中的size()

共有1个答案

夏意蕴
2023-03-14

在c 17之前没有指定A=B的求值顺序,在c 17之后B保证在A之前求值,参见https://en.cppreference.com/w/cpp/language/eval_order规则20。

valMap[val]=valMap的行为。大小() 在c 14中未指定,您应该使用:

auto size = valMap.size();
valMap[val] = size;

或者使用emplace来避免问题,这比依赖[]自动插入一个不存在的值更明确:

valMap.emplace(val, size);

 类似资料:
  • null 我相信这个答案是正确的,但我无法证明。有人能证明它为什么起作用或提供一个反例吗?

  • 我们的LinkedIn APP不再适用于V2的演变。我已经尝试了几次,但未能创建正确的令牌。我正在寻求帮助以创建正确的授权链接以获取令牌。应用程序的错误目前是“清空开放2访问令牌” 我创建了一个新的LinkedIn应用程序来取代我们的旧应用程序。我试着按照LinkedIn和微软的指示去做,但是我的努力产生了下面的错误 我最近的尝试是: https://www.linkedin.com/oauth/

  • 我正在尝试限制关键字输入。 每当用户输入一个关键字,它就会在该关键字后面加上'span',例如。 如下面的html代码。 我可以限制字,但计数不准确,但当它达到5,它停止输入。 如果我刷新页面,我可以再输入一个,然后再阻止我一次。 奇怪的是,如果我为使用id就不起作用了。我得利用课堂。 我试过把,但不起作用,我必须保留它的资本。 jQuery: HTML:

  • 问题内容: 我正在尝试将log4j配置为使用,但我不断收到中继访问被拒绝的错误。在笔记本电脑上直接从共享托管环境执行代码时,出现此错误。 这是相关的配置: 如果改用,则会收到身份验证错误。我的主机位于DreamHost上,因此如果有人使用DreamHost电子邮件帐户设置了log4j,则可获赠积分。 问题答案: 原来我只是把属性都弄错了。应该:

  • 问题内容: A. dispatchTouchEvent→onInterceptTouchEvent→onTouchEvent B. dispatchTouchEvent→onTouchEvent→onInterceptTouchEvent C. onInterceptTouchEvent→dispatchTouchEvent→onTouchEvent D. onTouchEvent→onInter

  • 问题内容: 让我们以一个简单的对象为例。我想确定“不为空” 是橙色还是灰色。 我相信AND首先出现,然后是OR。不过我有点模糊,所以这是我的问题: 有人可以指导我完成此声明,以便我确定会发生什么吗? 另外,如果加上括号会怎样?这会改变操作顺序吗? 我的操作顺序会因语言而异吗? 问题答案: Java教程有一个列表,说明了运算符优先级。将首先计算相等运算符,然后是。括号将先计算,因此添加括号可以更改顺