In diesem Zusammenhang bedeutet & eine Referenz - also gibt foo eine Referenz auf ein int und nicht auf ein int zurück.
Ich bin mir nicht sicher, ob Sie schon mit Zeigern gearbeitet hätten, aber es ist eine ähnliche Idee, dass Sie den Wert nicht tatsächlich aus der Funktion zurückgeben - stattdessen übergeben Sie die Informationen, die erforderlich sind, um den Speicherort im Speicher zu finden, an dem sich dieser befindet int ist.
Zusammenfassend lässt sich sagen, dass Sie einem Funktionsaufruf keinen Wert zuweisen. Sie verwenden eine Funktion, um eine Referenz abzurufen, und weisen dann den Wert, auf den verwiesen wird, einem neuen Wert zu. Es ist leicht zu glauben, dass alles auf einmal passiert, aber in Wirklichkeit erledigt der Computer alles in einer genauen Reihenfolge.
Wenn Sie sich fragen - der Grund, warum Sie einen Segfault erhalten, ist, dass Sie ein numerisches Literal '2' zurückgeben -, ist dies der genaue Fehler, den Sie erhalten würden, wenn Sie einen const int definieren und dann versuchen würden, ihn zu ändern Wert.
Wenn Sie noch nichts über Zeiger und dynamisches Gedächtnis gelernt haben, würde ich dies zunächst empfehlen, da es einige Konzepte gibt, die meiner Meinung nach schwer zu verstehen sind, es sei denn, Sie lernen sie alle gleichzeitig.