c++ - 三元运算符并通过常量引用延长临时对象的生命周期

标签 c++ c++11 copy-constructor temporary-objects

看到之后a local reference-to-const may prolong the life of a temporary ,我遇到了有条件地将本地常量引用绑定(bind)到函数参数或函数调用的临时结果的需要,即:

class Gizmo
{
    // Rule of Five members implemented
};

Gizmo Frobnicate(const Gizmo& arg);

void ProcessGizmo(const Gizmo& arg, bool frobnicate)
{
    const Foo& local = frobnicate ? Frobnicate(arg) : arg;
    // Perform some work on local
}

一个实际的例子: bool 值指定是否压缩一个缓冲区,你想写统一的代码来操作 local无论哪种方式。

但是,上面的示例在 arg 上调用了 Gizmo 的复制构造函数什么时候frobnicatefalse . 我设法通过更改 Frobnicate(arg) 来避免调用复制构造函数至 static_cast<const Gizmo&>(Frobnicate(arg)) .

我的问题变成了:三元运算符如何与有关将本地常量引用绑定(bind)到临时引用的规则交互?我的解决方案是否合法且行为良好?

最佳答案

不,它表现不佳。为了延长生命周期,必须将临时对象直接绑定(bind)到引用。添加转换后,绑定(bind)不再是直接的,生成的引用变为悬空。

我们可以通过一些简单的测试代码看到这一点:

#include <iostream>
struct Gizmo
{
    ~Gizmo() { std::cout << "Gizmo destroyed\n"; }
};

Gizmo Frobnicate(const Gizmo& arg) { return arg; }

void ProcessGizmo(const Gizmo& arg, bool frobnicate)
{
    const Gizmo& local = frobnicate ? static_cast<const Gizmo&>(Frobnicate(arg)) : arg;
    // Perform some work on local
    (void) local;
    std::cout << "Processing\n";
}

int main(){
    Gizmo g;
    ProcessGizmo(g, true);
    std::cout << "Processed\n";
}

prints :

Gizmo destroyed
Processing
Processed
Gizmo destroyed

第一个 Gizmo destroyed 消息来自 Frobnicate() 的返回值;它在该行的末尾被销毁 - 没有生命周期延长。

一个明显的解决方法是将处理转移到另一个函数中:

void DoProcessGizmo(const Gizmo& arg) { /* process the Gizmo */ }

void ProcessGizmo(const Gizmo& arg, bool frobnicate)
{
    return frobnicate ? DoProcessGizmo(Frobnicate(arg)) : DoProcessGizmo(arg);
}

关于c++ - 三元运算符并通过常量引用延长临时对象的生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28644398/

相关文章:

c++ - Qt 前向声明产生错误

C++11 递归可变参数模板

java - 复制构造函数断言错误

c++ - [Boost]::DI 从注入(inject)器创建唯一的 shared_ptr 对象

c++ - 更正 gtk、gtkmm 和 opencv 的 CMakeLists.txt 文件

c++ - 调整串口读取参数

c++ - std::atomic 到底是什么?

c++ - vector.size() 始终返回 0

c++ - 为什么在分配发生时调用参数化构造函数?

c++ - C++中是否有任何部分复制构造函数?