【问题标题】:Ranged base for loop over temporary reference C++11临时引用 C++11 上的远程循环基数
【发布时间】:2018-05-31 19:08:04
【问题描述】:

我想知道以下是否有效:

#include <iostream>
#include <vector>

std::vector<int>& getVec()
{
    static std::vector<int> vec{1, 2, 3, 4, 5};
    return vec;
}

int main()
{
    for (const auto& i : getVec())
    {
        std::cout << "i = " << i << std::endl;
    }
    return 0;
}

基本上我不确定来自getVec() 的临时文件的生命周期。我已经查看了this postthis one,但情况有点不同,因为我的函数返回了对static 数据的引用。具体来说,我想知道场景是否违反了规定规则中的以下异常:

  • 在函数调用中临时绑定到引用参数 [...]

或者如果这确实是安全代码。我认为这是安全的,但只是想确定一下。

【问题讨论】:

  • 这里没有临时向量。您只是在迭代 getVecvec
  • 好吧,我有点困惑,尽管基于范围的 for 循环可能正在创建对在 getVec 中返回的 vector 的临时引用。感谢您的澄清。如果您愿意,请发布答案,我会将其标记为答案。
  • 基于范围的 for 循环基本上只是调用 begin()end() 并扩展至基于迭代器的循环。参见例如here

标签: c++ c++11 for-loop static rvalue-reference


【解决方案1】:

是的,这是完全有效且定义明确的。

对于虚变量rangebeginend,您的问题中基于范围的 for 循环被定义为等效于以下内容:

auto&& range = getVec();
auto begin = std::begin(range);
auto end = std::end(range);
for (; begin != end; ++begin)
{
    const auto& i = *begin;
    {
        std::cout << "i = " << i << std::endl;
    }
}

引用折叠规则应用后,range 的类型变为std::vector&lt;int&gt;&amp;。这意味着永远不会创建临时对象。循环遍历getVec 中定义的静态向量。

如果getVec 改为按值返回,则range 的类型将为std::vector&lt;int&gt;&amp;&amp;,并应用生命周期延长。这会将临时对象的生命周期延长到引用的生命周期,并且一切仍然完全有效。

【讨论】:

    猜你喜欢
    • 2015-02-17
    • 1970-01-01
    • 2015-11-03
    • 1970-01-01
    • 2015-10-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-08
    相关资源
    最近更新 更多