“ int & foo()”在 C + + 中是什么意思?

在阅读有关左值和右值的 这个解释代码时,下面几行代码让我印象深刻:

int& foo();
foo() = 42; // OK, foo() is an lvalue

我在 g + + 中试过,但编译器说“对 foo ()的未定义引用”

int foo()
{
return 2;
}


int main()
{
int& foo();
foo() = 42;
}

它编译得很好,但是运行它会得到一个 内存区段错误

int& foo();

自己编译和运行都没有任何问题。

这个代码是什么意思?如何为函数调用赋值,为什么不赋右值?

29708 次浏览

int& foo(); is a function returning a reference to int. Your provided function returns int without reference.

没问题

int& foo()
{
static int i = 42;
return i;
}


int main()
{
int& foo();
foo() = 42;
}

解释是假设 foo有一些合理的实现,它返回对有效 int的左值引用。

这种执行可能是:

int a = 2; //global variable, lives until program termination


int& foo() {
return a;
}

现在,由于 foo返回一个左值引用,我们可以为返回值赋一些值,如下所示:

foo() = 42;

这将使用值 42更新全局 a,我们可以通过直接访问变量或再次调用 foo来检查 42:

int main() {
foo() = 42;
std::cout << a;     //prints 42
std::cout << foo(); //also prints 42
}

链接页面上的示例代码只是一个虚函数声明。它不会编译,但是如果定义了某个函数,它通常会正常工作。这个例子的意思是“如果你有一个带有这个签名的函数,你可以像这样使用它”。

在您的示例中,foo显然是基于签名返回一个左值,但是您返回一个转换为左值的右值。这显然是注定要失败的。你可以这样做:

int& foo()
{
static int x;
return x;
}

成功的方法是改变 x 的值:

foo() = 10;

int & foo();表示 foo()返回对变量的引用。

考虑下面的代码:

#include <iostream>
int k = 0;


int &foo()
{
return k;
}


int main(int argc,char **argv)
{
k = 4;
foo() = 5;
std::cout << "k=" << k << "\n";
return 0;
}

这个代码显示:

$./a.out K = 5

因为 foo()返回对全局变量 k的引用。

在修改后的代码中,您将返回的值强制转换为引用,该引用将无效。

int& foo();

声明一个名为 foo 的函数,该函数返回对 int的引用。这些示例没有给出可以编译的函数的定义。如果我们用

int & foo()
{
static int bar = 0;
return bar;
}

现在我们有了一个返回对 bar的引用的函数。因为 bar 是 static,所以在调用函数之后它会继续存在,所以返回对它的引用是安全的。如果我们这么做了

foo() = 42;

我们将42赋值给 bar,因为我们赋值给引用,而引用只是 bar的别名。如果我们再次调用函数

std::cout << foo();

它会打印42,因为我们设置 bar以上。

int &foo(); declares a function called foo() with return type int&. If you call this function without providing a body then you are likely to get an undefined reference error.

在第二次尝试中,您提供了一个函数 int foo()。这与 int& foo();声明的函数的返回类型不同。因此,有两个相同 foo的声明不匹配,这违反了单一定义规则(One Definition Rule) ,导致了未定义的行为(不需要诊断)。

For something that works, take out the local function declaration. They can lead to silent undefined behaviour as you have seen. Instead, only use function declarations outside of any function. Your program could look like:

int &foo()
{
static int i = 2;
return i;
}


int main()
{
++foo();
std::cout << foo() << '\n';
}

在这种情况下,& 表示引用-so foo 返回对 int 而不是 int 的引用。

I'm not sure if you'd have worked with pointers yet, but it's a similar idea, you're not actually returning the value out of the function - instead you're passing the information needed to find the location in memory where that int is.

总而言之,你并没有给函数调用赋值——而是使用函数来获取引用,然后将被引用的值赋给一个新值。人们很容易认为所有事情都是同时发生的,但实际上计算机是按照精确的顺序来做所有事情的。

如果你想知道——你得到一个 Segfault 的原因是因为你返回了一个数字字面值“2”——那么这就是如果你定义一个 const int 然后尝试修改它的值会得到的精确错误。

如果你还没有学过指针和动态内存,那么我建议你先学一些我认为很难理解的概念,除非你同时学习它们。

您拥有的函数 foo ()是一个返回对整数的引用的函数。

假设 foo 最初返回5稍后在主函数中输出 foo() = 10;然后输出 foo 它会输出10而不是5。

我希望这是有道理的:)

我对编程也是个新手。看到这样的问题让你思考很有趣! :)

所有其他的答案在函数内部声明一个静态。我想这可能会让你感到困惑,所以看看这个:

int& highest(int  & i, int  & j)
{
if (i > j)
{
return i;
}
return j;
}


int main()
{
int a{ 3};
int b{ 4 };
highest(a, b) = 11;
return 0;
}

Because highest() returns a reference, you can assign a value to it. When this runs, b will be changed to 11. If you changed the initialization so that a was, say, 8, then a would be changed to 11. This is some code that might actually serve a purpose, unlike the other examples.