繁体   English   中英

C ++通过引用

[英]C++ pass-by-reference

我正在尝试使用以下简单代码进行C ++传递引用:

#include <iostream>
int square(int &x)
{
return x*x;
}
int main()
{
std::cout<<"Square of 4 is: "<<square(4)<<std::endl;
return 0;
}

但是,当我尝试运行它时,得到以下信息:

在此处输入图片说明

更新

在基于@Pablo Santa Cruz的答案修改代码后,出现以下错误(我只是捕获了部分错误):

在此处输入图片说明

这是为什么?

谢谢。

您不能将临时变量传递给非恒定引用。

使square接受const int &

int square(const int &x)
{
    return x*x;
}

如果期望引用,则不能传递常量( 4 )。

必须传递一个变量:

int n = 4;
square(n);

话虽如此,您可能想要这样的东西:

void square(int &x)
{
   x = x*x;
}

不是返回int的函数。

这是因为C ++ 03的第8.5.3 5节:

T1” is initialized by an expression of type “ T2” as follows: 对类型“ T1”的引用由类型“ T2”的表达式初始化,如下所示:
  • 如果初始化表达式
    • T1” is reference-compatible with “ T2,” or 是左值(但不是位字段),并且“ T1”与“ T2”具有参考兼容性,或者
    • T3,” where “ T1” is reference-compatible with “ T3” 92) (this conversion is selected by enumerating the applicable conversion functions (13.3.1.6) and choosing the best one through over- load resolution (13.3)), 具有类类型(即T2是类类型),并且可以隐式转换为类型“ T3”的左值,其中“ T1”与“ T3” 92引用兼容)(此转换由列举适用的转换函数(13.3.1.6)并通过过载分辨率选择最佳的转换函数(13.3)),
    然后在第一种情况下将引用直接绑定到初始化表达式左值,在第二种情况下将引用绑定到转换的左值结果。 在这些情况下,引用被称为直接绑定到初始化程序表达式。 [ 注意:普通的左值到右值(4.1),数组到指针(4.2)和函数到指针(4.3)标准转换是不需要的,因此,当此类直接绑定到左值时完成。 ]
  • shall be const). 否则,引用应为非易失性const类型(即为const)。
    • T1” is reference-compatible with “ T2,” the reference is bound in one of the following ways (the choice is implementation-defined. 如果初始化器表达式是一个右值,T2是类类型,并且“ T1”与“ T2”是引用兼容的,则该引用将通过以下方式之一进行绑定(选择由实现定义)。
      • 引用绑定到右值表示的对象(请参见3.10)或该对象内的子对象。
      • T2” [sic] is created, and a constructor is called to copy the entire rvalue object into the temporary. 将创建一个类型为“ T2”的临时文件,然后调用构造函数将整个右值对象复制到该临时文件中。 引用绑定到临时项或临时项中的子对象。
    • T1” is created and initialized from the initializer expression using the rules for a non-reference copy initialization (8.5). 否则,将使用非引用副本初始化(8.5)的规则从初始化程序表达式创建和初始化类型为“ T1”的临时文件。 然后将引用绑定到临时目录。 must be the same cv-qualification as, or greater cv- qualification than, ; 如果T1被参考相关到必须是相同的CV-资格,或更大的CV-资格比 否则,程序格式不正确。

*" refers to the modifiers "const" and "volatile", and "T*" refer to type names. 上面的“ *”是指修饰符“ const”和“ volatile”,而“ T *”是指类型名称。 = "const", T = "int"), const volatile std::string ( = "const volatile", T = "std::string"), char* ( = "", T = "char*"). 例如, const int =“ const”,T =“ int”), const volatile std::string =“ const volatile”,T =“ std :: string”), char* =“” ,T =“ char *”)。

简而言之, rvalue只允许绑定到const引用。

更新资料

如果您的square现在返回void(代码或未发生),则新的错误是因为没有operator<<(std::out&, void)

编译器为常量4创建一个临时对象,该对象不能作为非常量引用传递给函数。 main创建一个int对象,并将其传递给函数,或者通过const-reference或副本采用function参数。

报关单

int square(int& x);

表示函数square可能会更改其参数(尽管实际上不是)。 因此,调用square(4)是荒谬的:程序需要准备好更改数字4。

正如人们已经指出的那样,您可以更改函数以指定它不会更改其参数:

int square(const int& x); // pass reference to const type
// OR
int square(int x);        // pass by value

或者,您可以使用可以修改的值来调用原始square

int square(int& x);
// ...
int num = 4;
square(num);
// now (as far as the compiler knows) num might no longer be 4!

引用必须是l值-基本上,您可以在赋值语句的左侧看到该值。

因此,基本上,您需要首先在main分配一个变量。 然后,您可以将其传递到square

引用是另一个变量的别名。 “ 4”不是变量,因此您的引用没有别名。 因此,编译器抱怨。

您想要的是:

#include <iostream>
int square(int x)
{
    return(x * x);
}
int main()
{
    std::cout << "Square of 4 is: "<< square(4) << std::endl;
    return 0;
}

您是否注意到我是如何摆脱& int square(int &x) &表示通过引用传递。 它需要一个变量。 4square(4)是一个常数。

使用传递引用,可以更改x的值:

void square2(int &x)
{
    x = x * x;
    return;
}

现在:

int x = 5;
square2(x);
// x == 25

虽然,我认为您不想要这个。 (您吗?)第一种方法要好得多。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM