关于将临时对象传递给const引用

时间:2017-02-13 09:53:41

标签: c++ reference

在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>的函数吗?

2 个答案:

答案 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)引用初始化对象将调用复制构造函数。函数的参数将是所引用对象的副本。