使用右值引用对 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)
然后从导致未定义行为的悬空引用中读取。
我的部分程序执行如下操作:
#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)
然后从导致未定义行为的悬空引用中读取。