加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 如何在范围表达式中延长临时的生命周期?

发布时间:2020-12-16 03:34:27 所属栏目:百科 来源:网络整理
导读:在使用ranged-for循环时,我正在获取悬空引用.考虑以下C 14表达式(下面的完整示例程序): for(auto wheel: Bike().wheels_reference()) wheel.inflate(); 它的输出是: Wheel() Wheel() Bike()~Bike() with 0 inflated wheels.~Wheel()~Wheel() Wheel::inflat
在使用ranged-for循环时,我正在获取悬空引用.考虑以下C 14表达式(下面的完整示例程序):
for(auto& wheel: Bike().wheels_reference())
        wheel.inflate();

它的输出是:

Wheel()
 Wheel()
 Bike()
~Bike() with 0 inflated wheels.
~Wheel()
~Wheel()
 Wheel::inflate()
 Wheel::inflate()

显然有些事情是非常错误的.车轮超出其使用寿命,结果为0,而不是预期的2.

一个简单的解决方法是在主要部分为Bike引入一个变量.但是,我不控制main或Wheel中的代码.我只能更改struct Bike.

有没有办法通过改变自行车来修复这个例子?

一个成功的解决方案解决方案要么在编译时失败,要么计算2个充气轮胎并且不会触及超出其生命周期的任何物体.

附录:编译就绪源

#include <cstdlib>
#include <iostream>
#include <array>
#include <algorithm>
using std::cout;
using std::endl;

struct Wheel
{
    Wheel() { cout << " Wheel()" << endl; }
    ~Wheel() { cout << "~Wheel()" << endl; }
    void inflate() { inflated = true; cout << " Wheel::inflate()" << endl; }
    bool inflated = false;
};

struct Bike
{
    Bike() { cout << " Bike()" << endl; }
    ~Bike() {
        cout << "~Bike() with " << std::count_if(wheels.begin(),wheels.end(),[](auto& w) { return w.inflated; }) << " inflated wheels." << endl;
    }
    std::array<Wheel,2>& wheels_reference() { return wheels; }
    std::array<Wheel,2> wheels{Wheel(),Wheel()};
};

int main()
{
    for(auto& wheel: Bike().wheels_reference())
        wheel.inflate();
    return EXIT_SUCCESS;
}

解决方法

删除wheels_reference的rvalue重载.
std::array<Wheel,2>& wheels_reference() & { return wheels; }
std::array<Wheel,2>& wheels_reference() && = delete;

这样您就不会返回对临时成员的引用.

您对Bike类的示例用法

for(auto& wheel: Bike().wheels_reference())
    wheel.inflate();

然后拒绝编译(clang 3.4输出):

test.cpp:31:29: error: call to deleted member function 'wheels_reference'
    for(auto& wheel: Bike().wheels_reference())
                     ~~~~~~~^~~~~~~~~~~~~~~~
test.cpp:24:27: note: candidate function has been explicitly deleted
    std::array<Wheel,2>& wheels_reference() && = delete;
                          ^
test.cpp:23:27: note: candidate function not viable: no known conversion from 'Bike' to 'Bike' for object argument
    std::array<Wheel,2>& wheels_reference() & { return wheels; }

如果临时的生命周期是手动扩展的东西工作.

Bike&& bike = Bike();
for(auto& wheel: bike.wheels_reference())
    wheel.inflate();

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读