【问题标题】:Can I rely on std::map::operator[] to touch?我可以依靠 std::map::operator[] 来触摸吗?
【发布时间】:2016-01-10 11:47:12
【问题描述】:

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

#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;
    }
}

我能否确定编译器不会优化 m[i]; 语句,因为我没有对它们“做”任何事情? (不明确分配给,不读取。)

【问题讨论】:

    标签: c++ c++11 dictionary stl


    【解决方案1】:

    是的,您可以确定。优化调用会改变程序的可观察行为,并且不允许编译器这样做(RVO 除外)。

    这被称为as-if rule

    【讨论】:

    • 你能引用一个来源吗?
    • 谢谢。我可以建议在您的答案中引用这一点吗? “如果一个实际的实现可以推断出它的值没有被使用并且没有产生影响程序可观察行为的副作用,那么它就不需要评估表达式的一部分。”从您链接的已接受答案中的第二个引用开始。
    • @cp.engr 老实说,我觉得另一个问题的链接很好地解释了这个问题,而不是在这里复制一些不完整的答案部分。特别是因为这是一个现场资源,因此非常安全,不会出现链接衰减。
    • 鉴于我提出的问题,我只是认为这是最相关的一点。当然,链接应该仍然存在。
    • @cp.engr 在这里引用这个我仍然感觉不好。一方面,这甚至没有首先涉及“可观察行为”是什么。那么,该部分只是一个“解释性脚注”。最后但并非最不重要的一点是,我们已经对这个网站上的 as-if 规则有一个很好的解释,我可以参考。这符合不重复答案的精神;例如,如果标准措辞要在某些细节上进行更改,我们将只需要编辑该帖子而不是进行寻宝游戏。 TL;DR:报价太不完整,不值得 IMO。
    【解决方案2】:

    是的,你可以确定。当您认为有问题的行与此等效时,它可能更直观:

    m.operator[](i);
    

    ...而且你不希望任意函数调用在你的程序之外被优化,如果他们做任何事情的话。

    【讨论】:

      【解决方案3】:

      [] 运算符确实默认构造了如果您不为其分配某些内容,则该键所在位置的值。

      Reference Link

      如果 k 不匹配容器中任何元素的键,则 函数使用该键插入一个新元素并返回一个引用 到它的映射值。请注意,这总是增加容器 大小加一,即使没有为元素分配映射值( 元素是使用其默认构造函数构造的)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-02-27
        • 2018-01-20
        • 2020-05-06
        • 1970-01-01
        • 2011-12-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多