迭代通过右值容器 [英] Iterating through an rvalue container

查看:204
本文介绍了迭代通过右值容器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码是否导致未定义的行为?

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:


  1. std :: map< ...& code>是一个r值,其生命周期将被扩展,直到完整表达式

  2. std :: vector< int> 是一个l值引用(进入一个对象),其生命周期是对象的生命周期。

  1. std::map<...> is an r-value, its lifetime will be expanded until the end of the full-expression
  2. std::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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆