c – 通过右值容器迭代

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

std::map<int, vector<int>> foo()
{
return ...
}

BOOST_FOREACH(const int& i, foo()[42])
{
std::cout << i << std::endl;
}

如果未定义,修复它的好方法是什么?如果我使用c 11 range-for循环而不是BOOST_FOREACH怎么办?

解决方法:

不幸的是,这很可能是未定义的行为.

问题是你有两个级别:

> std :: map< ...>是一个r值,它的生命周期将扩展到完整表达式的结束
> std :: vector< int>&是一个l值引用(进入一个对象),它的生命周期是对象的生命周期.

问题出现是因为代码(粗略地)扩展到类似的东西:

// 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的匹配,但在这种情况下,我们得到:

// non-standard gcc extension, very handy to model temporaries:
std::vector<int>& __container = { std::map<...> m = foo(); m[42] };

因此__container最终指向幽冥.

上一篇:Spring事务


下一篇:声明式事务注解@Transactional源码剖析