C++引用传递

发布于 2024-10-14 03:37:28 字数 505 浏览 7 评论 0原文

我正在尝试使用这个简单的代码进行 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 的回答修改代码后出现以下错误(我只是屏幕截图了部分错误):

在此处输入图像描述

这是为什么?

谢谢。

I'm trying C++ pass-by-reference using this simple code:

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

But, when I try to run it, I get the following:

enter image description here

UPDATE

I get the following error after modifying the code based on @Pablo Santa Cruz's answer (I just screen captured part of the error):

enter image description here

Why is that?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

小兔几 2024-10-21 03:37:28

您不能将临时引用传递给非常量引用。

square 接受 const int &

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

You cannot pass temporaries to non-constant references.

Make square accept a const int &:

int square(const int &x)
{
    return x*x;
}
万劫不复 2024-10-21 03:37:28

如果您需要引用,则无法传递常量 (4)。

必须传递一个变量:

int n = 4;
square(n);

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

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

不是返回 int 的函数。

You can't pass a constant (4) if you are expecting a reference.

You must pass a variable:

int n = 4;
square(n);

Having said that, you probably want something like this:

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

Not a function returning an int.

剪不断理还乱 2024-10-21 03:37:28

这是因为 C++03 的 § 8.5.3 5:

对类型“cv1 T1”的引用由类型“cv2 T2”的表达式初始化,如下所示:

  • 如果初始化表达式
    • 是左值(但不是位字段),并且“cv1 T1”与“cv2 T2”引用兼容,或者
    • 具有类类型(即,T2 是类类型),并且可以隐式转换为“cv3 T3”类型的左值,其中“cv1 T1”与“cv3 T3”92 引用兼容)(通过枚举适用的转换函数 (13.3.1.6) 并通过重载解析 (13.3) 选择最佳的函数来选择此转换),< /里>

    那么在第一种情况下,引用直接绑定到初始化表达式左值,在第二种情况下,引用绑定到转换的左值结果。在这些情况下,引用被称为直接绑定到初始化表达式。 [注意:通常的左值到右值 (4.1)、数组到指针 (4.2) 和函数到指针 (4.3) 标准转换是不需要的,因此被抑制,当完成与左值的直接绑定时。 ]

  • 否则,引用应为非易失性 const 类型(即,cv1 应为 const)。
    • 如果初始化表达式是右值,T2 是类类型,并且“cv1 T1”与“cv2 T2”引用兼容,则引用将被绑定通过以下方式之一(选择是实现定义的。
      • 引用绑定到右值表示的对象(参见 3.10)或该对象内的子对象。
      • 创建类型为“cv1 T2”[原文如此]的临时对象,并调用构造函数将整个右值对象复制到临时对象中。该引用绑定到临时对象或临时对象中的子对象。
    • 否则,将使用非引用复制初始化 (8.5) 的规则从初始化表达式创建并初始化类型为“cv1 T1”的临时变量。然后该引用将绑定到临时对象。如果 T1 与 T2 引用相关,则 cv1 的 cv 资格必须与 cv2 相同或更高;否则,该程序的格式不正确。

上面,“cv*”指的是修饰符“const”和“volatile”,“T*”指的是类型名称。例如,const int (cv = "const", T = "int")、const volatile std::string ( cv =“常量易失性”,T =“std::string”),char*cv=“”,T =“char*”) 。

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

更新

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

It's because of § 8.5.3 5 of C++03:

A reference to type “cv1 T1” is initialized by an expression of type “cv2 T2” as follows:

  • If the initializer expression
    • is an lvalue (but is not a bit-field), and “cv1 T1” is reference-compatible with “cv2 T2,” or
    • has a class type (i.e., T2 is a class type) and can be implicitly converted to an lvalue of type “cv3 T3,” where “cv1 T1” is reference-compatible with “cv3 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)),

    then the reference is bound directly to the initializer expression lvalue in the first case, and the reference is bound to the lvalue result of the conversion in the second case. In these cases the reference is said to bind directly to the initializer expression. [Note: the usual lvalue-to-rvalue (4.1), array-to-pointer (4.2), and function-to-pointer (4.3) standard conversions are not needed, and therefore are suppressed, when such direct bindings to lvalues are done. ]

  • Otherwise, the reference shall be to a non-volatile const type (i.e., cv1 shall be const).
    • If the initializer expression is an rvalue, with T2 a class type, and “cv1 T1” is reference-compatible with “cv2 T2,” the reference is bound in one of the following ways (the choice is implementation-defined.
      • The reference is bound to the object represented by the rvalue (see 3.10) or to a sub-object within that object.
      • A temporary of type “cv1 T2” [sic] is created, and a constructor is called to copy the entire rvalue object into the temporary. The reference is bound to the temporary or to a sub-object within the temporary.
    • Otherwise, a temporary of type “cv1 T1” is created and initialized from the initializer expression using the rules for a non-reference copy initialization (8.5). The reference is then bound to the temporary. If T1 is reference-related to T2, cv1 must be the same cv-qualification as, or greater cv- qualification than, cv2; otherwise, the program is ill-formed.

Above, "cv*" refers to the modifiers "const" and "volatile", and "T*" refer to type names. For example, const int (cv = "const", T = "int"), const volatile std::string (cv = "const volatile", T = "std::string"), char* (cv = "", T = "char*").

In short, rvalues are allowed to bind only to const references.

Update

If your square now returns void (code or it didn't happen), then the new error is because there is no operator<<(std::out&, void).

入画浅相思 2024-10-21 03:37:28

编译器为常量 4 创建一个临时对象,该对象不能作为非常量引用传递给函数。在 main 中创建一个 int 对象并将其传递给函数,或者通过常量引用或复制获取函数参数。

Compiler creates a temporary object for constant 4 which can not be passed to a function as a non-const reference. Create a int object in main and pass it to the function or take the function parameter by const-reference or by copy.

反目相谮 2024-10-21 03:37:28

该声明

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!

The declaration

int square(int& x);

says that the function square may change its argument (although it doesn't really). So to call square(4) is ridiculous: the program needs to be ready to change the number 4.

As people have noted, you can either change the function to specify that it won't change its argument:

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

Or you can call your original square using a value that can be modified.

int square(int& x);
// ...
int num = 4;
square(num);
// now (as far as the compiler knows) num might no longer be 4!
柒七 2024-10-21 03:37:28

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

所以基本上,您需要首先分配给 main 中的变量。然后你可以将它传递到square中。

A reference must be an l-value-- basically, something you can see on the left side of an assignment statement.

So basically, you need to assign to a variable in main first. Then you can pass it into square.

束缚m 2024-10-21 03:37:28

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

A reference aliases another variable. "4" is not a variable, and therefore your reference has nothing to alias. The compiler therefore complains.

风吹过旳痕迹 2024-10-21 03:37:28

你想要的是这样的:

#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) 中的 & 了吗? & 表示按引用传递。它需要一个变量。 square(4) 中的 4 是一个常量。

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

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

现在:

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

尽管如此,我认为您不希望这样。 (你是吗??)第一种方法要好得多。

What you want is this:

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

Did you notice how I got rid of the & in int square(int &x)? The & means pass-by-reference. It takes a variable. The 4 in square(4) is a constant.

Using pass-by-reference, you can change the value of x:

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

Now:

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

Although, I don't think you want this. (Do you??) The first method is a lot better.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文