在看到a local reference-to-const may prolong the life of a temporary后,我遇到了有条件地将本地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
}
一个实际示例:boolean指定是否压缩缓冲区,并且您希望编写在local
上运行的统一代码。
但是,当arg
为frobnicate
时,上面的示例在false
上调用了Gizmo的复制构造函数。
我设法通过将Frobnicate(arg)
更改为static_cast<const Gizmo&>(Frobnicate(arg))
来避免调用复制构造函数。
我的问题变成:三元运算符如何与关于将本地引用到const绑定到临时的规则进行交互?我的解决方案是否合法且表现良好?
答案 0 :(得分: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";
}
这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);
}