有时在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 (假设不可更改)。但是,在大数组的情况下,对传递的参数的临时副本进行存储会有问题。
答案 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
的情况下会更有效率。