【发布时间】:2014-09-29 17:10:31
【问题描述】:
临时对象有时是用 C++ 创建的。 STL valarray 类的一个示例是 slice_array,每次选择 valarray 的一系列索引时都会调用它。 http://www.cplusplus.com/reference/valarray/slice_array/
我的问题是这样的:
当将这些临时对象作为参数传递给函数时,是传递这些对象的副本,还是仅传递一个引用?
例如想象一下这两个简单的函数:
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(假定它是不可更改的)。但是,在大数组的情况下,制作传递参数的临时副本会影响内存。
【问题讨论】:
-
编译您的代码并启用优化。此外,生成程序集列表并查看发生了什么。
-
你为什么不把你的参数改成
const double * inp,然后你把另一个参数改成const valarray<double>& v -
simple_product 真的一成不变吗?因为,在我看来,这是错误的。如果无法更改,当您将 const valarray 传递给函数时,这将是可接受的
const_cast用法,它不会修改它,但由于某种原因不会将其视为 const。 -
@NeilKirk:这将是我希望工作的创可贴,但如果传递一个真正恒定的对象,那将是 UB。
-
@Deduplicator 它不是 UB,因为函数 simple_product 不会修改它。这是一个创可贴,但他说功能不能改变。
标签: c++ function arguments pass-by-reference rvalue-reference