在C ++中,“int&foo()”是什么意思?
在阅读关于左值和右值的这个解释时,这些代码行出来了:
int& foo(); foo() = 42; // OK, foo() is an lvalue
我在g ++中试过,但编译器说“未定义的引用foo()”。 如果我添加
int foo() { return 2; } int main() { int& foo(); foo() = 42; }
它编译好,但运行它给出了分段错误 。 只是线路
int& foo();
本身编译和运行没有任何问题。
这个代码是什么意思? 你怎么能给函数调用赋值,为什么不是右值呢?
解释是假设有一个合理的实现foo
返回一个有效的int
的左值引用。
这样的实现可能是:
int a = 2; //global variable, lives until program termination int& foo() { return a; }
现在,由于foo
返回一个左值引用,所以我们可以给返回值分配一些东西,如下所示:
foo() = 42;
这将更新全局a
值42
,我们可以通过直接访问variables或再次调用foo
来检查:
int main() { foo() = 42; std::cout << a; //prints 42 std::cout << foo(); //also prints 42 }
所有其他答案在函数内声明一个静态的。 我想这可能会让你困惑,所以看看这个:
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; }
由于highest()
返回一个引用,所以可以给它赋值。 当这个运行的时候, b
会被改为11.如果你改变了初始值使得a
是8,那么a
将被改为11.这是一些代码,可能实际上是为了一个目的,而不像其他的例子。
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();
用返回typesint&
声明一个名为foo()
的函数。 如果你在不提供body的情况下调用这个函数,那么你可能会得到一个未定义的引用错误。
在第二次尝试中,你提供了一个函数int foo()
。 这int& foo();
声明的函数具有不同的返回typesint& foo();
。 所以你有两个相同的foo
声明不匹配,这违反了One Definition Rule导致未定义的行为(不需要诊断)。
对于有用的东西,取出本地函数声明。 他们可以导致沉默未定义的行为,如你所见。 相反,只能在任何函数之外使用函数声明。 您的程序可能如下所示:
int &foo() { static int i = 2; return i; } int main() { ++foo(); std::cout << foo() << '\n'; }
int& foo();
是一个返回int
的引用的函数。 你提供的函数返回int
而没有引用。
你可以做
int& foo() { static int i = 42; return i; } int main() { int& foo(); foo() = 42; }
int & foo();
意味着foo()
返回一个variables的引用。
考虑这个代码:
#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()
返回对全局variablesk
的引用。
在您修改的代码中,您正在将返回的值转换为引用,然后该引用无效。
在这种情况下,&意味着引用 – 所以foo返回一个int的引用,而不是int。
我不确定你是否已经使用了指针,但它是一个类似的想法,你实际上并没有返回值的function – 而是传递所需的信息来查找内存中的位置int是。
所以总结一下,你并没有为函数调用赋值 – 你正在使用一个函数来获得一个引用,然后把被引用的值赋值给一个新的值。 想想一切都很容易,但事实上,电脑会按照精确的顺序来处理所有事情。
如果你想知道 – 你得到一个段错误的原因是因为你要返回一个数字字符'2' – 所以这是你得到的确切的错误,如果你要定义一个const int,然后尝试修改它值。
如果你还没有学到关于指针和dynamic内存的知识,那么我build议首先考虑一些我认为难以理解的概念,除非你一次全部学习。
链接页面上的示例代码只是一个虚函数声明。 它不能编译,但是如果你定义了一些函数,它一般会起作用。 这个例子的意思是“如果你有这个签名的function,你可以像这样使用它”。
在你的例子中, foo
显然是基于签名返回一个左值,但是你返回的左值被转换为左值。 这显然决定了失败。 你可以这样做:
int& foo() { static int x; return x; }
并通过改变x的值来成功说出:
foo() = 10;
你有的函数foo()是一个函数,它返回一个整数的引用。
所以我们假设原来的foo返回5,然后在你的主函数中,你说foo() = 10;
,然后打印出foo,它会打印10而不是5。
我希望这是有道理的 :)
我也是编程新手。 看到这样的问题让你觉得很有趣! 🙂