三元运算符,通过引用到const来延长临时对象的生命周期

Doo*_*ins 4 c++ copy-constructor temporary-objects c++11

在看到本地引用const可能会延长临时的生命之后,我遇到了有条件地将本地reference-to-const绑定到函数参数或函数调用的临时结果的需要,即:

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
}
Run Code Online (Sandbox Code Playgroud)

一个实际的例子:boolean指定是否压缩缓冲区,并且您希望编写以local任一方式操作的统一代码.

上面的例子,但是,在调用小玩意儿的拷贝构造函数argfrobnicatefalse.我设法通过更改Frobnicate(arg)为避免复制构造函数的调用static_cast<const Gizmo&>(Frobnicate(arg)).

我的问题变成:三元运算符如何与关于将本地引用到const绑定到临时的规则进行交互?我的解决方案是否合法且表现良好?

T.C*_*.C. 5

不,它不是很好.对于要发生的生命周期扩展,临时必须直接绑定到引用.添加演员表后,绑定不再是直接的,结果引用变为悬空.

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

#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";
}
Run Code Online (Sandbox Code Playgroud)

打印:

Gizmo destroyed
Processing
Processed
Gizmo destroyed
Run Code Online (Sandbox Code Playgroud)

第一条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);
}
Run Code Online (Sandbox Code Playgroud)