C++中的函数如何以最小的复制返回值或引用?

Jes*_*der 10 c++ c++11

我有一个委托给另外两个的函数,根据某些运行时条件返回引用或值:

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)

在除最后一个之外的所有情况下,不应该(基于运行时行为)复制返回值.

如果返回类型fooX,那么在案例2中将有一个额外的副本; 但如果返回类型是const X&,则情况1和3是未定义的行为.

是否可以通过返回某种代理来确保上述用途具有最少的副本?


说明:由于"你做错了"的形式出现了重大的阻碍,我想我会解释原因.

想象一下,我有一个类型的数组T or function<T()>(意味着这个数组的元素是类型的T,或者它们是返回的函数T).通过这个数组元素的"值",我的意思是,值本身或评估函数时的返回值.

如果get_value_of_array(int index)按值返回,那么在数组只包含一个元素的情况下,我不得不做一个额外的复制.这就是我想要避免的.


进一步说明:如果答案是"那是不可能的",那对我来说没问题.我很乐意看到这方面的证据 - 理想的形式是"假设有一种类型Proxy<X>可以解决你的问题.那么......"

Man*_*rse 6

你要找的是一个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)

  • @ Cheersandhth.-Alf:显然,OP的声明是为了传达这个想法,而不是确切的语法.在OP的情况下不可能获得那种确切的语法,因为返回的值是引用还是在运行时确定的值,具体取决于所讨论的数组的内容. (2认同)