使用右值引用对 STL 容器未定义行为的已擦除元素?

Is using rvalue reference to erased element of STL container undefined behavior?

我的部分程序执行如下操作:

#include <unordered_set>
#include <unordered_map>

std::unordered_map<std::string, int> G{{"1", 10}};

int m(const std::string& i, std::unordered_set<std::string>& v) {
    v.erase(i);
    return G.at(i);
}

int main() {
    std::unordered_set<std::string> v {"1"};
    const std::string& remove_this = *v.begin();
    return m(remove_this, v);
}

该程序应该可以在 linux 和 windows 之间移植。当用 g++ 编译时,程序运行良好并且 returns 10,正如预期的那样。但是,当使用 VS 2017 编译时,程序中止,抛出 std::out_of_range。通过最微不足道的调试工作,我发现函数 m 中的 i 在调用 G.at 之前被销毁了。 (都没有优化)

据我了解,对 v.begin() 的 const 引用应该过期到 m returns(g++ 情况)。但是MSVC显然不同意。

是否定义了这个未定义的行为或实现?实际上,const 引用传递的参数什么时候过期?

参数 i 一直存在到 m 结束。但是,i 引用的对象在 v.erase(i) 之后消失,留下 i 作为悬空引用。 G.at(i) 然后从导致未定义行为的悬空引用中读取。