迭代通过右值容器 [英] Iterating through an rvalue container
问题描述
以下代码是否导致未定义的行为?
Is the following code causing undefined behavior?
std::map<int, vector<int>> foo()
{
return ...
}
BOOST_FOREACH(const int& i, foo()[42])
{
std::cout << i << std::endl;
}
如果未定义,修复它的好方法是什么?如果我使用c ++ 11范围为循环而不是BOOST_FOREACH怎么办?
If undefined, What is the good way to fix it? What if I use c++11 range-for loop instead of BOOST_FOREACH?
推荐答案
这是很可能是未定义的行为。
This is, unfortunately, most probably undefined behavior.
问题是这里有两个级别:
The problem is that you have two levels here:
-
std :: map< ...& code>是一个r值,其生命周期将被扩展,直到完整表达式
-
std :: vector< int>
是一个l值引用(进入一个对象),其生命周期是对象的生命周期。
std::map<...>
is an r-value, its lifetime will be expanded until the end of the full-expressionstd::vector<int>&
is an l-value reference (into an object), its lifetime is that of the object.
出现这个问题的原因是代码(粗略地)扩展到如下:
The problem arises because the code (roughly) expands to something like:
// from
for (<init>: <expr>) {
<body>
}
// to
auto&& __container = <expr>;
for (auto __it = begin(container), __e = end(container); __it != __e; ++__it)
{
<init> = *__it;
<body>
}
这里的问题在于 __ container
:
auto&& __container = foo()[42];
如果只是 foo()
这将工作,因为 std :: map< ...>
的生命周期将扩展为匹配 __ container
,但在这种情况下我们得到:
If it where just foo()
, this would work, because the lifetime of std::map<...>
would be extended to match that of __container
, however in this case we get:
// non-standard gcc extension, very handy to model temporaries:
std::vector<int>& __container = { std::map<...> m = foo(); m[42] };
因此 __ container
这篇关于迭代通过右值容器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!