2015-08-15 110 views
-1

的代码片段是如下C++通过引用功能传递

#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; 
} 

从Q + = B型“INT”的右值中发生的类型的非const引用无效初始化“INT &”错误(一(q))。如何去错误,使这个程序打印所需的输出

+1

请相应地格式化您的代码示例! –

+2

“b”和“c”不一样吗? –

+0

你想要的输出是什么? – Amit

回答

0

你不能通过引用传递一个常量。

要打破你的代码。

int a(int m){ 
    return ++m; 
} 

这将在

int b(int &m){ 
    return ++m; 
} 

返回一个int(不断,如5)

那么你现在在技术上传递一个整数(常量)不是变量进入B.你必须将B作为变量传入。

尝试正是你有什么,但传递

int x = a(your_number_here); 
int z = b(x); 

编辑:

int main(void){ 

    int p=0,q=0; 
    int x = 5; 

    p = a(x); 
    q = b(p); 

    cout << q << endl; 
    return 0; 
} 

返回7.

+0

这里没有“常量”。不知道你为什么这么认为。 –

+0

@LightnessRacesinOrbit绝对有常量...不仅你不正确,但我的上面的帖子解决了他的问题。 他返回的左值不是左值。 –

+0

给我看一个常数。你没有提到的初始值“0”和“5”不计算在内。 –

0

的错误是试图调用一个函数,它有一个值的参考结果。这就像打电话b的值为b(1)。这不能工作...

+0

其实这是给乔治·萨默斯技术多选题书和回答的一个问题是322 – soul

+0

@soul:你为什么要重复上每一个答案同样对此有何评论?我们懂了。你从书中得到了这个。但是,这本书是错误的。 –

+0

'b(1)'不是“文字”。 –

0

函数调用是你通过引用传递。见下:

void foo (int* m) 
{ 
    (*m)++; 
} 

int main (void) 
{ 
    int a = 0; 
    foo (&a); 
    cout << a << endl; // prints 1 
} 
+0

@WhozCraig固定 – bpgeck

+0

其实这是乔治·萨默斯技术多选题书的问题,给出的答案是322 – soul

+0

-1:这答案是错的。这段代码传递一个指针(和'a'的地址)。 OP通过引用传递。 'Type&'和'&expression'是两个不同的东西。 –

1

蒂莫西·威廉姆斯Ĵ是一个或两个以下的事情:

  • 错误;
  • 教学C++,因为它涉及到仅Visual Studio中,没有发表免责声明它,这是不明智的。

引用不能绑定到临时对象。它在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'; 
} 

我也应该注意到,所引用的代码很混乱,似乎并没有比做作“测试您的知识”挑战其他目的。我不会太在意这点,而是从a proper book学习C++。毕竟,蒂莫西威廉姆斯声称上述计划产出322; it doesn't

0

所以这里b(int& m)引用一个整数。这样想一想。引用是编译器自动处理解引用操作的“安全指针”。

a(int m)返回值是一个临时的,即,它是,一旦超出范围作为函数返回,并将其值以某种方式被利用的临时值。所以你可以做x = a(15);和x将成为返回16的副本。这是一个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值参考。如果你有兴趣,可以查看它。

0

它不允许通过一个r值作为一个非const引用参数。这发生在你用(q)作为它的参数调用函数b的行中,这是一个r值(一个不是简单变量的表达式)。 所以,你需要首先调用和itsvalue存储在变量中,然后将此变量传递给B:

int main(void) 
{ 
    int p=0,q=0,r=0; 
    p+=a(b(p)); 
    int t=a(q); 
    q+=b(t); 
    r+=a(c(r)); 
    cout<<p<<q<<r; 
    return 0; 
}