传递临时对象作为参数(C ++)

时间:2014-09-29 17:10:31

标签: c++ function arguments pass-by-reference rvalue-reference

有时在C ++中创建临时对象。 STL valarray 类中的一个示例是 slice_array ,每次选择一系列valarray索引时都会调用它。 http://www.cplusplus.com/reference/valarray/slice_array/

我的问题是:

将这些临时对象作为参数传递给函数时,是传递这些对象的副本,还是只引用?

E.g。想象一下这两个天真的功能:

double simple_product(double* inp,int length){
  double res=1;
  for(int i=0;i<length;++i){
      res = res*inp[i];
  }
  return(res);
}

double sum_selected(valarray<double> v){

    simple_product(&v[0],v.size());
    return(v.sum());
}

如果我以下列方式打电话给他们:

valarray<double> valery(10,10);
size_t sel[] = {1,3,4};
valarray<size_t> selection (sel,3);
cout << sum_selected(valery[selection]);

是否会在函数 sum_selected 的堆栈中暂时创建一个大小为3 * size_t的新对象?

请注意,将该功能声明为:double sum_selected(valarray<double> & v) 不允许(临时对象只能绑定到const引用)。

这很有趣的原因是,例如在这里,不可能将函数声明为:

double sum_selected(const valarray<double> & v),因为无法调用函数 simple_product (假设不可更改)。但是,在大数组的情况下,对传递的参数的临时副本进行存储会有问题。

2 个答案:

答案 0 :(得分:2)

如果声明函数按值获取其参数,则按值传递,创建对象的新副本:

void f(thing t);           // pass by value

如果它被声明通过引用获取其参数,那么它通过引用传递。但它只能暂时按const rvalue 引用:

void f(thing const & t);   // OK: const lvalue reference
void f(thing && t);        // OK: rvalue reference
void f(thing & t);         // Error: lvalue reference can't bind to temporary

通过引用传递不会创建新对象,并且临时的生命周期在函数调用期间有效,直到创建它的语句结束。

答案 1 :(得分:1)

valarray<T>::operator[](valarray<size_t> const&)会为indirect_array<T>合格的运营商返回valarray<T>reference)或const,而不是slice_array。< / p>

如果您希望能够将所选元素作为连续数组访问,那么您需要将它们收集到一个连续的数组中。转换构造函数valarray<T>::valarray(indirect_array<T> const&)为您执行此操作。在这种情况下,引用语义将毫无用处,因为没有现有对象具有连续排列的所需元素。

将函数签名更改为double sum_selected(valarray<double> const&)对您的代码没有任何影响,因为无论如何构建了临时valarray<double>。在没有下标的情况下直接传递valery的情况下会更有效率。