4

我已经阅读了 C++ 面试问题的答案,其中有一个让我感到困惑:

问:C++ 编译器何时创建临时变量?

A: 如果函数参数是“const 引用”,编译器会通过以下两种方式生成临时变量。

a) 实际参数是正确的类型,但不是左值

double Cube(const double & num)
{
  num = num * num * num;
  return num;
}

double temp = 2.0;
double value = cube(3.0 + temp); // argument is a expression and not a Lvalue

b) 实际参数的类型错误,但类型可以转换为正确的类型

 long temp = 3L;
 double value = cuberoot(temp); // long to double conversion

我的问题是一旦函数参数是const 引用,为什么编译器会生成临时变量,这不是自相矛盾吗?另外,函数 Cube 是否应该因为修改了 const 参数而无法编译?

4

7 回答 7

7

我在这里看不到任何自相矛盾的东西。如果参数不是左值,或者类型错误,则引用不能直接附加到参数上,原因很明显;因此需要正确类型的中间临时。而是将引用附加到该临时文件。

Cube函数确实被破坏(格式错误),因为它试图修改一个const值。

于 2010-10-04T17:52:11.877 回答
3

在我看来是错误的 - gcc 会产生一个错误:

const_ref.cpp: In function ‘double cube(const double&)’:
const_ref.cpp:3: error: assignment of read-only reference ‘num’
于 2010-10-04T17:52:47.940 回答
2

编译器可以生成一个临时变量。它不必。

是的,Cube实际上不应该编译。

于 2010-10-04T17:52:57.063 回答
1

您可以将表达式的结果(包括隐式转换的结果)传递给对 const 的引用。理由是,虽然(const X & value)使用起来可能更便宜,但取决于类型 X 的复制成本,而不是(X value),效果几乎相同;value被使用但未修改(除非有一些冒险的常量转换)。因此,允许创建临时对象并将其传递给函数是无害的。

不允许使用指向 const 的指针或指向非 const 的引用这样做,因为可能会发生意外(和不好)的事情,例如您可能期望将 long temp 转换回 long,这不是不会发生。

你是正确num = num * num * num;的无效。这是文本中的一个错误,但它提出的论点成立。

于 2010-10-04T17:58:22.527 回答
0

因为在这两个示例中,都没有正确类型的非临时对象。

于 2010-10-04T17:53:06.383 回答
0

我相信您对功能立方体无法编译的看法是正确的。无论如何,这应该会失败,并且在我的编译器(VC++ 2008)上也是如此。

至于创建一个临时:

每当实际参数时,将创建一个支持 const 引用的临时值:

i) 不是正确的引用类型,ii) 可以隐式转换为正确的类型。

在示例 a) 中,根据您的问题,创建了一个临时double值来保存 value 3.0 + temp。然后使用对临时的引用来Cube()调用。const这是因为你不能有一个引用,3.0 + temp因为它不是一个变量(它是一个右值——表达式的结果),所以它没有内存地址,也不能支持引用。隐式地,编译器将创建一个临时double变量,然后为其分配3.0 + temp.

在您的示例 b) 中,您有一个long,但您的函数需要一个double。编译器会将 a 隐式转换long为 a double。它通过创建一个临时的double,为其分配转换后的值temp,然后创建const对临时的引用,并将该引用传递给cuberoot

于 2010-10-04T17:53:18.503 回答
0

是的。正如您在此处展示的那样,Cube() 应该无法编译。

于 2010-10-04T17:54:41.273 回答