在Andrew Koenig,Accelerated C ++的书中,他展示了以下代码:
vector<double> emptyvec()
{
vector<double> v; // no elements
return v;
}
grade(midterm, final, emptyvec());
现在,成绩函数对vector<double>
采用const引用。这意味着我应该复制emptyvec()返回的临时对象,因为它在堆栈中创建为局部变量和别名,这对我来说似乎很奇怪。这究竟是如何运作的?同样在另一个页面上,他将const引用传递给一个函数,该函数按值获取其参数并修改它们。可以将vector<double>
的const引用传递给参数期望vector<double>
的函数吗?
答案 0 :(得分:2)
这意味着我应该复制
emptyvec()
返回的临时对象,因为它是作为局部变量在堆栈中创建的
当然,它确实被复制了。但是,它被复制的位置由编译器指定,而不是由您的程序指定。
如果编译器无法为临时引用传递临时值,那么您将被迫执行此操作:
vector<double> tmp(emptyvec());
grade(midterm, final, tmp);
这几乎就是本书代码中场景背后发生的事情,除了代码无法访问tmp
变量。
可以将
vector<double>
的const引用传递给参数期望vector<double>
的函数吗?
是,只要参数按值传递,而不是通过引用传递。回想一下,复制构造函数需要const
引用。当你调用一个带vector<double>
并传递const vector<double>&
的函数时,C ++调用vector<double>
的构造函数,传递一个常量引用,并在函数内使用生成的副本。
答案 1 :(得分:2)
现在,成绩函数对向量采用const引用。这对我来说意味着应该复制emptyvec()返回的临时对象
grade
接受const引用这一事实不会影响emptyvec
返回的对象是否被复制。
这究竟是如何运作的?
如果按值返回局部变量,则从概念上制作局部变量的副本(或C ++ 11以来的移动)。
但是,c ++标准允许“删除”副本(和移动)。实际上,优化器可以选择在已复制到的位置构造返回的对象。这称为“(命名)返回值优化”。
同样在另一个页面上,他将const引用传递给一个函数,该函数按值获取其参数并修改它们。可以将向量的const引用传递给参数需要向量的函数吗?
使用相同类型的(const)引用初始化对象将调用复制构造函数。函数的参数将是所引用对象的副本。