我有一个委托给另外两个的函数,根据某些运行时条件返回引用或值:
X by_value() { ... }
const X& by_reference() { ... }
?? foo(bool b) {
if (b) {
return by_value();
} else {
return by_reference();
}
}
Run Code Online (Sandbox Code Playgroud)
我想选择我的函数的返回类型,以便调用者最小化复制; 例如:
const X& x1 = foo(true); // No copies
const X& x2 = foo(false); // No copies
X x3 = foo(true); // No copies, one move (or zero via RVO)
X x4 = foo(false); // One copy
Run Code Online (Sandbox Code Playgroud)
在除最后一个之外的所有情况下,不应该(基于运行时行为)复制返回值.
如果返回类型foo
是X
,那么在案例2中将有一个额外的副本; 但如果返回类型是const X&
,则情况1和3是未定义的行为.
是否可以通过返回某种代理来确保上述用途具有最少的副本?
说明:由于"你做错了"的形式出现了重大的阻碍,我想我会解释原因.
想象一下,我有一个类型的数组T or function<T()>
(意味着这个数组的元素是类型的T
,或者它们是返回的函数T
).通过这个数组元素的"值",我的意思是,值本身或评估函数时的返回值.
如果get_value_of_array(int index)
按值返回,那么在数组只包含一个元素的情况下,我不得不做一个额外的复制.这就是我想要避免的.
进一步说明:如果答案是"那是不可能的",那对我来说没问题.我很乐意看到这方面的证据 - 理想的形式是"假设有一种类型Proxy<X>
可以解决你的问题.那么......"
你要找的是一个sum-type(也就是说,一个可能的值是"可能的X
值加上可能的X const&
值"的类型).
在C++中,通常会调用它们variant
.这些通常实现为标记加上适当大小和对齐的数组,并且在运行时仅保留一个值.或者,它们通过动态分配和经典访问者模式实现.
例如,使用Boost.Variant,您可以声明要返回的函数boost::variant<X, X const&>
(实例):
boost::variant<X, X const&> foo(bool b) {
if (b) {
return by_value();
} else {
return by_reference();
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1551 次 |
最近记录: |