我也被类似的代码所迷惑 - 在拳头。这是“为什么我给函数调用赋值,以及为什么编译器对它感到满意?”我质疑自己。但是当你看到“后面”会发生什么时,它确实有道理。
由于cpp和其他poined出来,左值是“存储位置”有地址,我们可以给它们赋值。您可以在左值和右值on the internet的主题中找到更多信息。
当我们在看功能:
int& fun()
{
static int x = 10;
return x;
}
我感动&的类型,所以这是比较明显的,我们正在返回的引用为int。
我们看到我们有x,这是左值 - 它有地址,我们可以分配给它。它也是静态的,这使得它非常特殊 - 如果它不是静态的,变量的生命期(范围)将在离开函数时以堆栈展开结束,然后参考可指向宇宙中存在的任何黑洞。然而,由于x是静态的,即使在我们离开函数之后(以及当我们再次返回函数时)它也会存在,我们可以在函数之外访问它。
我们正在返回一个int的引用,由于我们返回x,它是对x的引用。然后,我们可以使用该参考来更改函数外部的x。所以:
int main()
{
fun();
我们只是调用函数。变量x(在乐趣函数的范围内)被创建,它的值为10赋值。即使在功能被留下之后,它的地址和价值仍然存在 - 但我们无法使用它的价值,因为我们没有地址。
fun() = 30;
我们调用的函数,然后改变X值。通过函数返回的引用更改值x。 注意:该函数被称为第一个,并且只有在函数调用完成后,然后,分配发生。
int& reference_to_x = fun(); // note the &
现在我们(终于)保持由该函数返回的参考X。现在我们可以改变x而不先调用函数。(reference_to_x将可能有相同的地址X有乐趣函数内)
int copy_of_x = fun(); // no & this time
这一次,我们创造新的int和我们刚才复制的X值(通过参考)。这个新的int有它自己的地址,它不指向x like reference_to_x是。
reference_to_x = 5;
我们分配X值5至基准,而我们甚至没有调用的函数。 copy_of_x未更改。
copy_of_x = 15;
我们换了新的int价值15 X没有改变,因为copy_of_x有它自己的地址。
}
由于6502和其他人指出的那样,我们使用返回引用了大量与容器和自定义的替换类似的方法。
std::map<std::string, std::string> map = {};
map["hello"] = "Ahoj";
// is equal to
map.operator[]("hello") = "Ahoj"; // returns reference to std::string
// could be done also this way
std::string& reference_to_string_in_map = map.operator[]("hello");
reference_to_string_in_map = "Ahoj";
我们使用可以有声明这样的地图功能:
std::string& map::operator[](const std::string& key); // returns reference
我们没有地址,我们“存储”在地图的字符串,所以我们称之为地图此重写功能,传递它以便map知道我们想要访问哪个字符串,并且它返回给我们的那个字符串的引用,我们可以用它来改变这个值。 注意:该函数再次被调用,并且只有在完成后(地图找到正确的字符串并返回对其的引用)才会进行分配。这就像有乐趣()= 10,只有更beatiful ...
希望这有助于人谁仍然woudn't甚至阅读其他的答案后明白了一切......
返回参考静态变量是左值(和法律)。你为什么认为应该有任何错误? –
'fun()'返回的值是'int&',它是'lvalue' –
评估引用*会导致*左值。 –