"int&foo()"在C++中的含义是什么?

Sos*_*sos 113 c++ function return-by-reference

在阅读关于左值和左值的这个解释时,这些代码行向我伸出:

int& foo();
foo() = 42; // OK, foo() is an lvalue
Run Code Online (Sandbox Code Playgroud)

我在g ++中尝试过它,但编译器说"对foo()的未定义引用".如果我加

int foo()
{
  return 2;
}

int main()
{
  int& foo();
  foo() = 42;
}
Run Code Online (Sandbox Code Playgroud)

它编译很好,但运行它会产生分段错误.就行了

int& foo();
Run Code Online (Sandbox Code Playgroud)

它本身既编译又运行没有任何问题.

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

Tar*_*ama 164

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

这样的实现可能是:

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

int& foo() {
    return a;
} 
Run Code Online (Sandbox Code Playgroud)

现在,因为foo返回左值引用,我们可以为返回值赋值,如下所示:

foo() = 42;
Run Code Online (Sandbox Code Playgroud)

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

int main() {
    foo() = 42;
    std::cout << a;     //prints 42
    std::cout << foo(); //also prints 42
}
Run Code Online (Sandbox Code Playgroud)

  • 鉴于对refrence的混淆,最好从样本中删除静态局部变量.初始化增加了不必要的复杂性,这是学习的障碍.让它成为一个全球性的. (8认同)

Kat*_*ory 71

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

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;
}
Run Code Online (Sandbox Code Playgroud)

因为highest()返回引用,所以可以为其赋值.当它运行时,b将更改为11.如果您更改了初始化a,例如8,那么a将更改为11.这是一些实际上可能用于某个目的的代码,与其他示例不同.

  • @AlexPetrenko即通用初始化.我碰巧在我方便的例子中使用它.对它没什么不妥 (6认同)
  • 是否有理由将int写入{3}而不是int a = 3?这种语法对我来说似乎不合适. (5认同)
  • 我知道这是什么.a = 3只是感觉更清洁.个人喜好) (3认同)

Nat*_*ica 31

int& foo();
Run Code Online (Sandbox Code Playgroud)

声明一个名为foo的函数,它返回对a的引用int.这个例子没有做的是给你一个你可以编译的函数的定义.如果我们使用

int & foo()
{
    static int bar = 0;
    return bar;
}
Run Code Online (Sandbox Code Playgroud)

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

foo() = 42;
Run Code Online (Sandbox Code Playgroud)

我们分配42是bar因为我们分配了引用,而引用只是一个别名bar.如果我们再次调用该函数

std::cout << foo();
Run Code Online (Sandbox Code Playgroud)

它将打印42,因为我们设置bar为上述.


M.M*_*M.M 15

int &foo();声明一个foo()用返回类型调用的函数int&.如果在不提供正文的情况下调用此函数,则可能会出现未定义的引用错误.

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

对于有效的东西,取出本地函数声明.如您所见,它们可能导致无声的未定义行为.相反,只在任何函数之外使用函数声明.您的程序可能如下所示:

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

int main()
{
    ++foo();  
    std::cout << foo() << '\n';
}
Run Code Online (Sandbox Code Playgroud)


Jar*_*d42 10

int& foo();是一个返回引用的函数int.您提供的函数返回时int没有引用.

你可能会这样做

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

int main()
{
    int& foo();
    foo() = 42;
}
Run Code Online (Sandbox Code Playgroud)


vy3*_*y32 7

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;
}
Run Code Online (Sandbox Code Playgroud)

此代码打印:

$ ./a.out k = 5

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

在修订后的代码中,您将返回的值转换为引用,然后该引用无效.


Dar*_*ett 5

在该上下文中,&表示引用 - 因此foo返回对int的引用,而不是int.

我不确定你是否已使用指针,但这是一个类似的想法,你实际上并没有从函数中返回值 - 而是你传递了在内存中找到位置所需的信息int是.

因此,总结一下,您没有为函数调用赋值 - 您正在使用函数来获取引用,然后将引用的值赋给新值.很容易认为一切都在同一时间发生,但实际上计算机会按照精确的顺序完成所有事情.

如果你想知道 - 你得到一个段错误的原因是因为你正在返回一个数字文字'2' - 所以如果你要定义一个const int然后尝试修改它,那就是你得到的确切错误值.

如果你还没有学过指针和动态记忆,那么我建议首先考虑一些我认为难以理解的概念,除非你一次性学习它们.