代码段如下
#include <iostream>
using namespace std;
int a(int m)
{
return ++m;
}
int b(int &m)
{
return ++m;
}
int c(int &m)
{
return ++m;
}
int main(void)
{
int p=0,q=0,r=0;
p+=a(b(p));
q+=b(a(q));
r+=a(c(r));
cout<<p<<q<<r;
return 0;
}
发生的错误是'int&amp;'类型的非const引用的无效初始化来自q + = b(a(q))的'int'类型的右值。如何进行错误以便该程序打印所需的输出
答案 0 :(得分:1)
Timothy J Williams是以下一项或两项:
引用不能绑定到临时对象。它在C ++中是不允许的。 Visual Studio允许它作为非标准扩展,但就是这样。有些人感到困惑,并认为这意味着它是有效的C ++。不是。
在通过引用将它们传递到任何地方之前,您必须将函数调用的结果(如b(1)
)存储到命名变量中。
int main()
{
int p = 0, q = 0, r = 0;
int result_of_b_p = b(p);
p += a(result_of_b_p);
int result_of_a_q = a(q);
q += b(result_of_a_q);
int result_of_c_r = c(r);
r += a(result_of_c_r);
std::cout << p << q << r << '\n';
}
我还应该注意,所引用的代码令人困惑,似乎没有其他目的,除了人为的和测试你的知识&#34;挑战。我不太关注这一点,而是从a proper book学习C ++。毕竟,蒂莫西·威廉姆斯声称上述计划产出322; it doesn't
答案 1 :(得分:0)
该错误是尝试调用带有值的引用的函数的结果。这就像使用值文字b
调用b(1)
。那不行......
答案 2 :(得分:0)
所以这里b(int& m)
引用一个整数。这样想吧。引用是一个&#34;安全指针&#34;编译器自动处理解除引用操作。
a(int m)
的返回值是临时的,即它是一个临时值,一旦函数返回并且以某种方式使用了它的值,就会超出范围。因此,您可以执行x = a(15);
,x将成为返回的16
的副本。这就是r值。一种&#34;临时&#34; (r因为它位于表达式的右侧)。因此,当你有一个指向临时值的指针时,在大多数情况下都没有意义。例如,在以下代码中
int* return_local() {
int a = 10;
return &a;
}
这会给你一个编译器警告。因为您不想将指针绑定到超出范围的值。类似地,一旦函数返回并且其值已被利用,您就不希望引用超出范围的对象。这就是您的代码中出现错误的原因。 a(int m)
返回一个r值,当你执行b(a(q)
时,你试图将引用绑定到一个r值
现在有一种称为r值引用的东西,它在语法中采用void some_func(int&& rvalue_reference)
形式。 &&
表示r值引用不参考引用。如果你有兴趣,请查阅。