怀疑C ++面试问题

时间:2010-10-04 17:43:21

标签: c++ reference const temporary

我读过Answers to C++ interview questions,其中有一个让我困惑:

  

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

     

答:假设函数参数是“const引用”,编译器会以下列两种方式生成临时变量。

     

a)实际参数是正确的类型,但它不是Lvalue

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参数?

7 个答案:

答案 0 :(得分:7)

我认为这里没有任何自相矛盾的地方。如果参数不是左值,或者类型错误,则由于显而易见的原因,引用不能直接附加到参数;因此需要一个正确类型的中间临时。该引用附加到该临时值。

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

答案 1 :(得分:3)

我看错了 - 而且gcc会产生错误:

const_ref.cpp: In function ‘double cube(const double&)’:
const_ref.cpp:3: error: assignment of read-only reference ‘num’

答案 2 :(得分:2)

编译器可以生成临时变量。它没有。

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

答案 3 :(得分:1)

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

你不允许使用指针指向const或引用指向非const指令,因为可能会发生意外(和坏)事情,例如你可能期望将长时间强制转换为long,这不会发生。

你对num = num * num * num;无效是正确的。这是文本中的一个错误,但它所提出的论点仍然存在。

答案 4 :(得分:0)

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

答案 5 :(得分:0)

我相信你对函数多维数据集无法编译是正确的。无论如何,这应该失败,它确实在我的编译器(VC ++ 2008)上。

至于创建一个临时的:

只要实际参数:

,就会创建一个支持const引用的临时值

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

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

在您的示例b)中,您有long,但您的功能需要double。编译器将隐式地将long转换为double。它通过创建临时double,为其分配转换后的temp值,然后创建对const的临时引用,并将该引用传递给cuberoot <来实现此目的/ p>

答案 6 :(得分:0)

是。正如你在这里展示的那样,Cube()应该无法编译。