C++ 传递引用函数
C++ passing by reference function
代码片段如下
#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(a(q)) 处从类型 'int' 的右值对类型 'int&' 的非常量引用进行无效初始化。如何解决错误以便此程序打印所需的输出
该错误是由于尝试调用采用带值引用的函数而导致的。这就像用值文字 b(1)
调用 b
。那不行...
函数调用 是您通过引用传递的地方。见下文:
void foo (int* m)
{
(*m)++;
}
int main (void)
{
int a = 0;
foo (&a);
cout << a << endl; // prints 1
}
不能通过引用传递常量。
分解你的代码。
int a(int m){
return ++m;
}
这将 return 一个整数(常量,例如 5)
然后在
int b(int &m){
return ++m;
}
从技术上讲,您现在将整数(常量)而不是 变量 传递给 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;
}
Returns7.
Timothy J Williams 是以下其中一项或两项:
- 错误;
- 只教授与 Visual Studio 相关的 C++,而不放弃它,这是不明智的。
引用不能绑定到临时对象。在 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';
}
我还应该指出,引用的代码令人困惑,而且除了人为的 "test your knowledge" 挑战之外似乎没有任何用处。我不会太在意这个,而是从 a proper book. After all, Timothy Williams claims that the above program outputs 322; it doesn't.
学习 C++
所以这里 b(int& m)
引用了一个整数。这样想。引用是一个 "safe pointer",编译器会自动为其处理解引用操作。
a(int m)
的 return 值是一个临时值,即一旦函数 returns 及其值被使用,它就会超出范围某种程度上来说。所以你可以做 x = a(15);
并且 x 将成为 returned 16
的副本。这就是 r 值。一种 "temporary"(r 因为它在表达式的右侧)。所以当你有一个指向临时值的指针时,在大多数情况下它没有意义。例如在下面的代码中
int* return_local() {
int a = 10;
return &a;
}
这会给你一个编译器警告。因为您不想将指针绑定到超出范围的值。同样,您不希望引用一个对象,该对象一旦函数 returned 并且其值已被使用就会超出范围。这就是为什么您的代码中存在错误的原因。 a(int m)
return 是右值,当你这样做时 b(a(q)
你试图将引用绑定到右值
现在有一种称为右值引用的东西,它的语法形式为 void some_func(int&& rvalue_reference)
。 &&
表示右值引用而不是引用引用。有兴趣的可以看看
不允许将右值作为非常量引用参数传递。这发生在以 a(q) 作为参数调用函数 b 的行中,它是一个右值(不是简单变量的表达式)。
所以需要先调用a并将其值存入一个变量,然后将这个变量传递给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;
}
代码片段如下
#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(a(q)) 处从类型 'int' 的右值对类型 'int&' 的非常量引用进行无效初始化。如何解决错误以便此程序打印所需的输出
该错误是由于尝试调用采用带值引用的函数而导致的。这就像用值文字 b(1)
调用 b
。那不行...
函数调用 是您通过引用传递的地方。见下文:
void foo (int* m)
{
(*m)++;
}
int main (void)
{
int a = 0;
foo (&a);
cout << a << endl; // prints 1
}
不能通过引用传递常量。
分解你的代码。
int a(int m){
return ++m;
}
这将 return 一个整数(常量,例如 5)
然后在
int b(int &m){
return ++m;
}
从技术上讲,您现在将整数(常量)而不是 变量 传递给 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;
}
Returns7.
Timothy J Williams 是以下其中一项或两项:
- 错误;
- 只教授与 Visual Studio 相关的 C++,而不放弃它,这是不明智的。
引用不能绑定到临时对象。在 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';
}
我还应该指出,引用的代码令人困惑,而且除了人为的 "test your knowledge" 挑战之外似乎没有任何用处。我不会太在意这个,而是从 a proper book. After all, Timothy Williams claims that the above program outputs 322; it doesn't.
学习 C++所以这里 b(int& m)
引用了一个整数。这样想。引用是一个 "safe pointer",编译器会自动为其处理解引用操作。
a(int m)
的 return 值是一个临时值,即一旦函数 returns 及其值被使用,它就会超出范围某种程度上来说。所以你可以做 x = a(15);
并且 x 将成为 returned 16
的副本。这就是 r 值。一种 "temporary"(r 因为它在表达式的右侧)。所以当你有一个指向临时值的指针时,在大多数情况下它没有意义。例如在下面的代码中
int* return_local() {
int a = 10;
return &a;
}
这会给你一个编译器警告。因为您不想将指针绑定到超出范围的值。同样,您不希望引用一个对象,该对象一旦函数 returned 并且其值已被使用就会超出范围。这就是为什么您的代码中存在错误的原因。 a(int m)
return 是右值,当你这样做时 b(a(q)
你试图将引用绑定到右值
现在有一种称为右值引用的东西,它的语法形式为 void some_func(int&& rvalue_reference)
。 &&
表示右值引用而不是引用引用。有兴趣的可以看看
不允许将右值作为非常量引用参数传递。这发生在以 a(q) 作为参数调用函数 b 的行中,它是一个右值(不是简单变量的表达式)。 所以需要先调用a并将其值存入一个变量,然后将这个变量传递给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;
}